// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.vehicles;

import fmod.fmod.FMODManager;
import fmod.fmod.FMODSoundEmitter;
import fmod.fmod.FMOD_STUDIO_PARAMETER_DESCRIPTION;
import fmod.fmod.IFMODParameterUpdater;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Map.Entry;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.joml.Vector4f;
import se.krka.kahlua.j2se.KahluaTableImpl;
import se.krka.kahlua.vm.KahluaTable;
import zombie.Lua.LuaEventManager;
import zombie.Lua.LuaManager;
import zombie.ai.states.StaggerBackState;
import zombie.ai.states.ZombieFallDownState;
import zombie.audio.BaseSoundEmitter;
import zombie.audio.DummySoundEmitter;
import zombie.audio.FMODParameter;
import zombie.audio.FMODParameterList;
import zombie.audio.GameSoundClip;
import zombie.audio.parameters.ParameterVehicleBrake;
import zombie.audio.parameters.ParameterVehicleEngineCondition;
import zombie.audio.parameters.ParameterVehicleGear;
import zombie.audio.parameters.ParameterVehicleLoad;
import zombie.audio.parameters.ParameterVehicleRPM;
import zombie.audio.parameters.ParameterVehicleRoadMaterial;
import zombie.audio.parameters.ParameterVehicleSkid;
import zombie.audio.parameters.ParameterVehicleSpeed;
import zombie.audio.parameters.ParameterVehicleSteer;
import zombie.audio.parameters.ParameterVehicleTireMissing;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.characters.BodyDamage.BodyPart;
import zombie.characters.BodyDamage.BodyPartType;
import zombie.core.Color;
import zombie.core.Core;
import zombie.core.Rand;
import zombie.core.SpriteRenderer;
import zombie.core.Translator;
import zombie.core.math.PZMath;
import zombie.core.network.ByteBufferWriter;
import zombie.core.opengl.Shader;
import zombie.core.physics.Bullet;
import zombie.core.physics.CarController;
import zombie.core.physics.Transform;
import zombie.core.physics.WorldSimulation;
import zombie.core.raknet.UdpConnection;
import zombie.core.skinnedmodel.ModelManager;
import zombie.core.skinnedmodel.animation.AnimationMultiTrack;
import zombie.core.skinnedmodel.animation.AnimationPlayer;
import zombie.core.skinnedmodel.animation.AnimationTrack;
import zombie.core.skinnedmodel.model.Model;
import zombie.core.skinnedmodel.model.SkinningData;
import zombie.core.skinnedmodel.model.VehicleModelInstance;
import zombie.core.skinnedmodel.model.VehicleSubModelInstance;
import zombie.core.textures.ColorInfo;
import zombie.core.textures.Texture;
import zombie.core.textures.TextureID;
import zombie.core.utils.UpdateLimit;
import zombie.debug.DebugLog;
import zombie.debug.DebugOptions;
import zombie.debug.LineDrawer;
import zombie.input.GameKeyboard;
import zombie.inventory.CompressIdenticalItems;
import zombie.inventory.InventoryItem;
import zombie.inventory.InventoryItemFactory;
import zombie.inventory.ItemContainer;
import zombie.inventory.ItemPickerJava;
import zombie.inventory.types.DrainableComboItem;
import zombie.inventory.types.HandWeapon;
import zombie.inventory.types.InventoryContainer;
import zombie.inventory.types.Key;
import zombie.iso.IsoCamera;
import zombie.iso.IsoCell;
import zombie.iso.IsoChunk;
import zombie.iso.IsoChunkMap;
import zombie.iso.IsoDirections;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoLightSource;
import zombie.iso.IsoMovingObject;
import zombie.iso.IsoObject;
import zombie.iso.IsoUtils;
import zombie.iso.IsoWorld;
import zombie.iso.Vector2;
import zombie.iso.SpriteDetails.IsoObjectType;
import zombie.iso.areas.SafeHouse;
import zombie.iso.objects.IsoDeadBody;
import zombie.iso.objects.IsoTree;
import zombie.iso.objects.IsoWindow;
import zombie.iso.objects.IsoWorldInventoryObject;
import zombie.iso.objects.RainManager;
import zombie.iso.objects.RenderEffectType;
import zombie.iso.objects.interfaces.Thumpable;
import zombie.iso.weather.ClimateManager;
import zombie.network.ClientServerMap;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.PacketTypes;
import zombie.network.PassengerMap;
import zombie.network.ServerOptions;
import zombie.popman.ObjectPool;
import zombie.radio.ZomboidRadio;
import zombie.scripting.ScriptManager;
import zombie.scripting.objects.ModelAttachment;
import zombie.scripting.objects.ModelScript;
import zombie.scripting.objects.VehicleScript;
import zombie.ui.TextManager;
import zombie.ui.UIManager;
import zombie.util.Pool;
import zombie.util.StringUtils;
import zombie.util.Type;
import zombie.util.list.PZArrayUtil;

public final class BaseVehicle extends IsoMovingObject implements Thumpable, IFMODParameterUpdater {
    public static final float RADIUS = 0.3F;
    public static final int FADE_DISTANCE = 15;
    public static final int RANDOMIZE_CONTAINER_CHANCE = 100;
    public static final byte noAuthorization = -1;
    private static final Vector3f _UNIT_Y = new Vector3f(0.0F, 1.0F, 0.0F);
    private static final PolygonalMap2.VehiclePoly tempPoly = new PolygonalMap2.VehiclePoly();
    public static final boolean YURI_FORCE_FIELD = false;
    public static boolean RENDER_TO_TEXTURE = false;
    public static float CENTER_OF_MASS_MAGIC = 0.7F;
    private static final float[] wheelParams = new float[24];
    private static final float[] physicsParams = new float[27];
    static final byte POSITION_ORIENTATION_PACKET_SIZE = 102;
    public static Texture vehicleShadow = null;
    public int justBreakConstraintTimer = 0;
    public BaseVehicle wasTowedBy = null;
    protected static final ColorInfo inf = new ColorInfo();
    private static final float[] lowRiderParam = new float[4];
    private final BaseVehicle.VehicleImpulse impulseFromServer = new BaseVehicle.VehicleImpulse();
    private final BaseVehicle.VehicleImpulse[] impulseFromSquishedZombie = new BaseVehicle.VehicleImpulse[4];
    private final ArrayList<BaseVehicle.VehicleImpulse> impulseFromHitZombie = new ArrayList();
    private final int netPlayerTimeoutMax = 30;
    private final Vector4f tempVector4f = new Vector4f();
    public final ArrayList<BaseVehicle.ModelInfo> models = new ArrayList();
    public IsoChunk chunk;
    public boolean polyDirty = true;
    private boolean polyGarageCheck = true;
    private float radiusReductionInGarage = 0.0F;
    public short VehicleID = -1;
    public int sqlID = -1;
    public boolean serverRemovedFromWorld = false;
    public VehicleInterpolation interpolation = null;
    public boolean waitFullUpdate;
    public float throttle = 0.0F;
    public double engineSpeed;
    public TransmissionNumber transmissionNumber;
    public final UpdateLimit transmissionChangeTime = new UpdateLimit(1000L);
    public boolean hasExtendOffset = true;
    public boolean hasExtendOffsetExiting = false;
    public float savedPhysicsZ = Float.NaN;
    public final Quaternionf savedRot = new Quaternionf();
    public final Transform jniTransform = new Transform();
    public float jniSpeed;
    public boolean jniIsCollide;
    public final Vector3f jniLinearVelocity = new Vector3f();
    private final Vector3f lastLinearVelocity = new Vector3f();
    public BaseVehicle.Authorization netPlayerAuthorization = BaseVehicle.Authorization.Server;
    public short netPlayerId = -1;
    public int netPlayerTimeout = 0;
    public int authSimulationHash = 0;
    public long authSimulationTime = 0L;
    public int frontEndDurability = 100;
    public int rearEndDurability = 100;
    public float rust = 0.0F;
    public float colorHue = 0.0F;
    public float colorSaturation = 0.0F;
    public float colorValue = 0.0F;
    public int currentFrontEndDurability = 100;
    public int currentRearEndDurability = 100;
    public float collideX = -1.0F;
    public float collideY = -1.0F;
    public final PolygonalMap2.VehiclePoly shadowCoord = new PolygonalMap2.VehiclePoly();
    public BaseVehicle.engineStateTypes engineState = BaseVehicle.engineStateTypes.Idle;
    public long engineLastUpdateStateTime;
    public static final int MAX_WHEELS = 4;
    public static final int PHYSICS_PARAM_COUNT = 27;
    public final BaseVehicle.WheelInfo[] wheelInfo = new BaseVehicle.WheelInfo[4];
    public boolean skidding = false;
    public long skidSound;
    public long ramSound;
    public long ramSoundTime;
    private VehicleEngineRPM vehicleEngineRPM = null;
    public final long[] new_EngineSoundId = new long[8];
    private long combinedEngineSound = 0L;
    public int engineSoundIndex = 0;
    public BaseSoundEmitter hornemitter = null;
    public float startTime = 0.0F;
    public boolean headlightsOn = false;
    public boolean stoplightsOn = false;
    public boolean windowLightsOn = false;
    public boolean soundHornOn = false;
    public boolean soundBackMoveOn = false;
    public boolean previouslyEntered = false;
    public final LightbarLightsMode lightbarLightsMode = new LightbarLightsMode();
    public final LightbarSirenMode lightbarSirenMode = new LightbarSirenMode();
    private final IsoLightSource leftLight1 = new IsoLightSource(0, 0, 0, 1.0F, 0.0F, 0.0F, 8);
    private final IsoLightSource leftLight2 = new IsoLightSource(0, 0, 0, 1.0F, 0.0F, 0.0F, 8);
    private final IsoLightSource rightLight1 = new IsoLightSource(0, 0, 0, 0.0F, 0.0F, 1.0F, 8);
    private final IsoLightSource rightLight2 = new IsoLightSource(0, 0, 0, 0.0F, 0.0F, 1.0F, 8);
    private int leftLightIndex = -1;
    private int rightLightIndex = -1;
    public final BaseVehicle.ServerVehicleState[] connectionState = new BaseVehicle.ServerVehicleState[512];
    protected BaseVehicle.Passenger[] passengers = new BaseVehicle.Passenger[1];
    protected String scriptName;
    protected VehicleScript script;
    protected final ArrayList<VehiclePart> parts = new ArrayList();
    protected VehiclePart battery;
    protected int engineQuality;
    protected int engineLoudness;
    protected int enginePower;
    protected long engineCheckTime;
    protected final ArrayList<VehiclePart> lights = new ArrayList();
    protected boolean createdModel = false;
    protected int skinIndex = -1;
    protected CarController physics;
    protected boolean bCreated;
    protected final PolygonalMap2.VehiclePoly poly = new PolygonalMap2.VehiclePoly();
    protected final PolygonalMap2.VehiclePoly polyPlusRadius = new PolygonalMap2.VehiclePoly();
    protected boolean bDoDamageOverlay = false;
    protected boolean loaded = false;
    protected short updateFlags;
    protected long updateLockTimeout = 0L;
    final UpdateLimit limitPhysicSend = new UpdateLimit(300L);
    Vector2 limitPhysicPositionSent = null;
    final UpdateLimit limitPhysicValid = new UpdateLimit(1000L);
    private final UpdateLimit limitCrash = new UpdateLimit(600L);
    public boolean addedToWorld = false;
    boolean removedFromWorld = false;
    private float polyPlusRadiusMinX = -123.0F;
    private float polyPlusRadiusMinY;
    private float polyPlusRadiusMaxX;
    private float polyPlusRadiusMaxY;
    private float maxSpeed;
    private boolean keyIsOnDoor = false;
    private boolean hotwired = false;
    private boolean hotwiredBroken = false;
    private boolean keysInIgnition = false;
    private long soundHorn = -1L;
    private long soundScrapePastPlant = -1L;
    private long soundBackMoveSignal = -1L;
    public long soundSirenSignal = -1L;
    private final HashMap<String, String> choosenParts = new HashMap();
    private String type = "";
    private String respawnZone;
    private float mass = 0.0F;
    private float initialMass = 0.0F;
    private float brakingForce = 0.0F;
    private float baseQuality = 0.0F;
    private float currentSteering = 0.0F;
    private boolean isBraking = false;
    private int mechanicalID = 0;
    private boolean needPartsUpdate = false;
    private boolean alarmed = false;
    private int alarmTime = -1;
    private float alarmAccumulator;
    private double sirenStartTime = 0.0;
    private boolean mechanicUIOpen = false;
    private boolean isGoodCar = false;
    private InventoryItem currentKey = null;
    private boolean doColor = true;
    private float brekingSlowFactor = 0.0F;
    private final ArrayList<IsoObject> brekingObjectsList = new ArrayList();
    private final UpdateLimit limitUpdate = new UpdateLimit(333L);
    public byte keySpawned = 0;
    public final Matrix4f vehicleTransform = new Matrix4f();
    public final Matrix4f renderTransform = new Matrix4f();
    private final Matrix4f tempMatrix4fLWJGL_1 = new Matrix4f();
    private final Quaternionf tempQuat4f = new Quaternionf();
    private final Transform tempTransform = new Transform();
    private final Transform tempTransform2 = new Transform();
    private final Transform tempTransform3 = new Transform();
    private BaseSoundEmitter emitter;
    private float brakeBetweenUpdatesSpeed = 0.0F;
    public long physicActiveCheck = -1L;
    private long constraintChangedTime = -1L;
    private AnimationPlayer m_animPlayer = null;
    public String specificDistributionId = null;
    private boolean bAddThumpWorldSound = false;
    private final SurroundVehicle m_surroundVehicle = new SurroundVehicle(this);
    private boolean regulator = false;
    private float regulatorSpeed = 0.0F;
    private static final HashMap<String, Integer> s_PartToMaskMap = new HashMap();
    private static final Byte BYTE_ZERO = (byte)0;
    private final HashMap<String, Byte> bloodIntensity = new HashMap();
    private boolean OptionBloodDecals = false;
    private long createPhysicsTime = -1L;
    private BaseVehicle vehicleTowing = null;
    private BaseVehicle vehicleTowedBy = null;
    public int constraintTowing = -1;
    private int vehicleTowingID = -1;
    private int vehicleTowedByID = -1;
    private String towAttachmentSelf = null;
    private String towAttachmentOther = null;
    private float towConstraintZOffset = 0.0F;
    private final ParameterVehicleBrake parameterVehicleBrake = new ParameterVehicleBrake(this);
    private final ParameterVehicleEngineCondition parameterVehicleEngineCondition = new ParameterVehicleEngineCondition(this);
    private final ParameterVehicleGear parameterVehicleGear = new ParameterVehicleGear(this);
    private final ParameterVehicleLoad parameterVehicleLoad = new ParameterVehicleLoad(this);
    private final ParameterVehicleRoadMaterial parameterVehicleRoadMaterial = new ParameterVehicleRoadMaterial(this);
    private final ParameterVehicleRPM parameterVehicleRPM = new ParameterVehicleRPM(this);
    private final ParameterVehicleSkid parameterVehicleSkid = new ParameterVehicleSkid(this);
    private final ParameterVehicleSpeed parameterVehicleSpeed = new ParameterVehicleSpeed(this);
    private final ParameterVehicleSteer parameterVehicleSteer = new ParameterVehicleSteer(this);
    private final ParameterVehicleTireMissing parameterVehicleTireMissing = new ParameterVehicleTireMissing(this);
    private final FMODParameterList fmodParameters = new FMODParameterList();
    public boolean isActive = false;
    public boolean isStatic = false;
    private final UpdateLimit physicReliableLimit = new UpdateLimit(500L);
    public boolean isReliable = false;
    public static final ThreadLocal<BaseVehicle.Vector2ObjectPool> TL_vector2_pool = ThreadLocal.withInitial(BaseVehicle.Vector2ObjectPool::new);
    public static final ThreadLocal<BaseVehicle.Vector2fObjectPool> TL_vector2f_pool = ThreadLocal.withInitial(BaseVehicle.Vector2fObjectPool::new);
    public static final ThreadLocal<BaseVehicle.Vector3fObjectPool> TL_vector3f_pool = ThreadLocal.withInitial(BaseVehicle.Vector3fObjectPool::new);
    public static final ThreadLocal<BaseVehicle.Matrix4fObjectPool> TL_matrix4f_pool = ThreadLocal.withInitial(BaseVehicle.Matrix4fObjectPool::new);
    public static final ThreadLocal<BaseVehicle.QuaternionfObjectPool> TL_quaternionf_pool = ThreadLocal.withInitial(BaseVehicle.QuaternionfObjectPool::new);
    public static final float PHYSICS_Z_SCALE = 0.82F;
    public static float PLUS_RADIUS = 0.15F;
    private int zombiesHits = 0;
    private long zombieHitTimestamp = 0L;
    public static final int MASK1_FRONT = 0;
    public static final int MASK1_REAR = 4;
    public static final int MASK1_DOOR_RIGHT_FRONT = 8;
    public static final int MASK1_DOOR_RIGHT_REAR = 12;
    public static final int MASK1_DOOR_LEFT_FRONT = 1;
    public static final int MASK1_DOOR_LEFT_REAR = 5;
    public static final int MASK1_WINDOW_RIGHT_FRONT = 9;
    public static final int MASK1_WINDOW_RIGHT_REAR = 13;
    public static final int MASK1_WINDOW_LEFT_FRONT = 2;
    public static final int MASK1_WINDOW_LEFT_REAR = 6;
    public static final int MASK1_WINDOW_FRONT = 10;
    public static final int MASK1_WINDOW_REAR = 14;
    public static final int MASK1_GUARD_RIGHT_FRONT = 3;
    public static final int MASK1_GUARD_RIGHT_REAR = 7;
    public static final int MASK1_GUARD_LEFT_FRONT = 11;
    public static final int MASK1_GUARD_LEFT_REAR = 15;
    public static final int MASK2_ROOF = 0;
    public static final int MASK2_LIGHT_RIGHT_FRONT = 4;
    public static final int MASK2_LIGHT_LEFT_FRONT = 8;
    public static final int MASK2_LIGHT_RIGHT_REAR = 12;
    public static final int MASK2_LIGHT_LEFT_REAR = 1;
    public static final int MASK2_BRAKE_RIGHT = 5;
    public static final int MASK2_BRAKE_LEFT = 9;
    public static final int MASK2_LIGHTBAR_RIGHT = 13;
    public static final int MASK2_LIGHTBAR_LEFT = 2;
    public static final int MASK2_HOOD = 6;
    public static final int MASK2_BOOT = 10;
    public float forcedFriction = -1.0F;
    protected final BaseVehicle.HitVars hitVars = new BaseVehicle.HitVars();

    public int getSqlId() {
        return this.sqlID;
    }

    public static Vector2 allocVector2() {
        return ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
    }

    public static void releaseVector2(Vector2 v) {
        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(v);
    }

    public static Vector3f allocVector3f() {
        return ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
    }

    public static void releaseVector3f(Vector3f vector3f) {
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
    }

    public BaseVehicle(IsoCell cell) {
        super(cell, false);
        this.setCollidable(false);
        this.respawnZone = new String("");
        this.scriptName = "Base.PickUpTruck";
        this.passengers[0] = new BaseVehicle.Passenger();
        this.waitFullUpdate = false;
        this.savedRot.w = 1.0F;

        for (int int0 = 0; int0 < this.wheelInfo.length; int0++) {
            this.wheelInfo[int0] = new BaseVehicle.WheelInfo();
        }

        if (GameClient.bClient) {
            this.interpolation = new VehicleInterpolation();
        }

        this.setKeyId(Rand.Next(100000000));
        this.engineSpeed = 0.0;
        this.transmissionNumber = TransmissionNumber.N;
        this.rust = (float)Rand.Next(0, 2);
        this.jniIsCollide = false;

        for (int int1 = 0; int1 < 4; int1++) {
            lowRiderParam[int1] = 0.0F;
        }

        this.fmodParameters.add(this.parameterVehicleBrake);
        this.fmodParameters.add(this.parameterVehicleEngineCondition);
        this.fmodParameters.add(this.parameterVehicleGear);
        this.fmodParameters.add(this.parameterVehicleLoad);
        this.fmodParameters.add(this.parameterVehicleRPM);
        this.fmodParameters.add(this.parameterVehicleRoadMaterial);
        this.fmodParameters.add(this.parameterVehicleSkid);
        this.fmodParameters.add(this.parameterVehicleSpeed);
        this.fmodParameters.add(this.parameterVehicleSteer);
        this.fmodParameters.add(this.parameterVehicleTireMissing);
    }

    public static void LoadAllVehicleTextures() {
        DebugLog.General.println("BaseVehicle.LoadAllVehicleTextures...");

        for (VehicleScript vehicleScript : ScriptManager.instance.getAllVehicleScripts()) {
            LoadVehicleTextures(vehicleScript);
        }
    }

    public static void LoadVehicleTextures(VehicleScript _script) {
        if (zombie.SystemDisabler.doVehiclesWithoutTextures) {
            VehicleScript.Skin skin0 = _script.getSkin(0);
            skin0.textureData = LoadVehicleTexture(skin0.texture);
            skin0.textureDataMask = LoadVehicleTexture("vehicles_placeholder_mask");
            skin0.textureDataDamage1Overlay = LoadVehicleTexture("vehicles_placeholder_damage1overlay");
            skin0.textureDataDamage1Shell = LoadVehicleTexture("vehicles_placeholder_damage1shell");
            skin0.textureDataDamage2Overlay = LoadVehicleTexture("vehicles_placeholder_damage2overlay");
            skin0.textureDataDamage2Shell = LoadVehicleTexture("vehicles_placeholder_damage2shell");
            skin0.textureDataLights = LoadVehicleTexture("vehicles_placeholder_lights");
            skin0.textureDataRust = LoadVehicleTexture("vehicles_placeholder_rust");
        } else {
            for (int _int = 0; _int < _script.getSkinCount(); _int++) {
                VehicleScript.Skin skin1 = _script.getSkin(_int);
                skin1.copyMissingFrom(_script.getTextures());
                LoadVehicleTextures(skin1);
            }
        }
    }

    private static void LoadVehicleTextures(VehicleScript.Skin skin) {
        skin.textureData = LoadVehicleTexture(skin.texture);
        if (skin.textureMask != null) {
            int _int = 0;
            _int |= 256;
            skin.textureDataMask = LoadVehicleTexture(skin.textureMask, _int);
        }

        skin.textureDataDamage1Overlay = LoadVehicleTexture(skin.textureDamage1Overlay);
        skin.textureDataDamage1Shell = LoadVehicleTexture(skin.textureDamage1Shell);
        skin.textureDataDamage2Overlay = LoadVehicleTexture(skin.textureDamage2Overlay);
        skin.textureDataDamage2Shell = LoadVehicleTexture(skin.textureDamage2Shell);
        skin.textureDataLights = LoadVehicleTexture(skin.textureLights);
        skin.textureDataRust = LoadVehicleTexture(skin.textureRust);
        skin.textureDataShadow = LoadVehicleTexture(skin.textureShadow);
    }

    public static Texture LoadVehicleTexture(String name) {
        int _int = 0;
        _int |= TextureID.bUseCompression ? 4 : 0;
        _int |= 256;
        return LoadVehicleTexture(name, _int);
    }

    public static Texture LoadVehicleTexture(String name, int flags) {
        return StringUtils.isNullOrWhitespace(name) ? null : Texture.getSharedTexture("media/textures/" + name + ".png", flags);
    }

    public void setNetPlayerAuthorization(BaseVehicle.Authorization _netPlayerAuthorization, int _netPlayerId) {
        this.netPlayerAuthorization = _netPlayerAuthorization;
        this.netPlayerId = (short)_netPlayerId;
        this.netPlayerTimeout = _netPlayerId == -1 ? 0 : 30;
        if (GameClient.bClient) {
            boolean _boolean = BaseVehicle.Authorization.Local.equals(_netPlayerAuthorization)
                || BaseVehicle.Authorization.LocalCollide.equals(_netPlayerAuthorization);
            if (this.getVehicleTowing() != null) {
                Bullet.setVehicleStatic(this, !_boolean);
                Bullet.setVehicleActive(this, _boolean);
                Bullet.setVehicleStatic(this.getVehicleTowing(), !_boolean);
                Bullet.setVehicleActive(this.getVehicleTowing(), _boolean);
            } else if (this.getVehicleTowedBy() != null) {
                Bullet.setVehicleStatic(this, !_boolean);
                Bullet.setVehicleActive(this, _boolean);
            } else {
                Bullet.setVehicleStatic(this, !_boolean);
                Bullet.setVehicleActive(this, _boolean);
            }
        }

        DebugLog.Vehicle
            .trace(
                "vid%s=%d pid=%d %s",
                this.getVehicleTowing() != null ? "-a" : (this.getVehicleTowedBy() != null ? "-b" : ""),
                this.getId(),
                _netPlayerId,
                _netPlayerAuthorization.name()
            );
    }

    public boolean isNetPlayerAuthorization(BaseVehicle.Authorization _netPlayerAuthorization) {
        return this.netPlayerAuthorization.equals(_netPlayerAuthorization);
    }

    public boolean isNetPlayerId(short _netPlayerId) {
        return this.netPlayerId == _netPlayerId;
    }

    public short getNetPlayerId() {
        return this.netPlayerId;
    }

    public String getAuthorizationDescription() {
        return String.format(
            "vid:%s(%d) pid:(%d) auth=%s static=%b active=%b",
            this.scriptName,
            this.VehicleID,
            this.netPlayerId,
            this.netPlayerAuthorization.name(),
            this.isStatic,
            this.isActive
        );
    }

    public static float getFakeSpeedModifier() {
        if (!GameClient.bClient && !GameServer.bServer) {
            return 1.0F;
        } else {
            float _float = (float)ServerOptions.instance.SpeedLimit.getValue();
            return 120.0F / Math.min(_float, 120.0F);
        }
    }

    public boolean isLocalPhysicSim() {
        return GameServer.bServer
            ? this.isNetPlayerAuthorization(BaseVehicle.Authorization.Server)
            : this.isNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide) || this.isNetPlayerAuthorization(BaseVehicle.Authorization.Local);
    }

    public void addImpulse(Vector3f vector3f0, Vector3f vector3f1) {
        if (!this.impulseFromServer.enable) {
            this.impulseFromServer.enable = true;
            this.impulseFromServer.impulse.set(vector3f0);
            this.impulseFromServer.rel_pos.set(vector3f1);
        } else if (this.impulseFromServer.impulse.length() < vector3f0.length()) {
            this.impulseFromServer.impulse.set(vector3f0);
            this.impulseFromServer.rel_pos.set(vector3f1);
            this.impulseFromServer.enable = false;
            this.impulseFromServer.release();
        }
    }

    public double getEngineSpeed() {
        return this.engineSpeed;
    }

    public String getTransmissionNumberLetter() {
        return this.transmissionNumber.getString();
    }

    public int getTransmissionNumber() {
        return this.transmissionNumber.getIndex();
    }

    public void setClientForce(float force) {
        this.physics.clientForce = force;
    }

    public float getClientForce() {
        return this.physics.clientForce;
    }

    public float getForce() {
        return this.physics.EngineForce - this.physics.BrakingForce;
    }

    private void doVehicleColor() {
        if (!this.isDoColor()) {
            this.colorSaturation = 0.1F;
            this.colorValue = 0.9F;
        } else {
            this.colorHue = Rand.Next(0.0F, 0.0F);
            this.colorSaturation = 0.5F;
            this.colorValue = Rand.Next(0.3F, 0.6F);
            int _int = Rand.Next(100);
            if (_int < 20) {
                this.colorHue = Rand.Next(0.0F, 0.03F);
                this.colorSaturation = Rand.Next(0.85F, 1.0F);
                this.colorValue = Rand.Next(0.55F, 0.85F);
            } else if (_int < 32) {
                this.colorHue = Rand.Next(0.55F, 0.61F);
                this.colorSaturation = Rand.Next(0.85F, 1.0F);
                this.colorValue = Rand.Next(0.65F, 0.75F);
            } else if (_int < 67) {
                this.colorHue = 0.15F;
                this.colorSaturation = Rand.Next(0.0F, 0.1F);
                this.colorValue = Rand.Next(0.7F, 0.8F);
            } else if (_int < 89) {
                this.colorHue = Rand.Next(0.0F, 1.0F);
                this.colorSaturation = Rand.Next(0.0F, 0.1F);
                this.colorValue = Rand.Next(0.1F, 0.25F);
            } else {
                this.colorHue = Rand.Next(0.0F, 1.0F);
                this.colorSaturation = Rand.Next(0.6F, 0.75F);
                this.colorValue = Rand.Next(0.3F, 0.7F);
            }

            if (this.getScript() != null) {
                if (this.getScript().getForcedHue() > -1.0F) {
                    this.colorHue = this.getScript().getForcedHue();
                }

                if (this.getScript().getForcedSat() > -1.0F) {
                    this.colorSaturation = this.getScript().getForcedSat();
                }

                if (this.getScript().getForcedVal() > -1.0F) {
                    this.colorValue = this.getScript().getForcedVal();
                }
            }
        }
    }

    @Override
    public String getObjectName() {
        return "Vehicle";
    }

    @Override
    public boolean Serialize() {
        return true;
    }

    public void createPhysics() {
        if (!GameClient.bClient && this.VehicleID == -1) {
            this.VehicleID = VehicleIDMap.instance.allocateID();
            if (GameServer.bServer) {
                VehicleManager.instance.registerVehicle(this);
            } else {
                VehicleIDMap.instance.put(this.VehicleID, this);
            }
        }

        if (this.script == null) {
            this.setScript(this.scriptName);
        }

        if (this.script != null) {
            if (this.skinIndex == -1) {
                this.setSkinIndex(Rand.Next(this.getSkinCount()));
            }

            if (!GameServer.bServer) {
                WorldSimulation.instance.create();
            }

            this.jniTransform
                .origin
                .set(
                    this.getX() - WorldSimulation.instance.offsetX,
                    Float.isNaN(this.savedPhysicsZ) ? this.getZ() : this.savedPhysicsZ,
                    this.getY() - WorldSimulation.instance.offsetY
                );
            this.physics = new CarController(this);
            this.savedPhysicsZ = Float.NaN;
            this.createPhysicsTime = System.currentTimeMillis();
            if (!this.bCreated) {
                this.bCreated = true;
                byte _byte = 30;
                if (zombie.SandboxOptions.getInstance().RecentlySurvivorVehicles.getValue() == 1) {
                    _byte = 0;
                }

                if (zombie.SandboxOptions.getInstance().RecentlySurvivorVehicles.getValue() == 2) {
                    _byte = 10;
                }

                if (zombie.SandboxOptions.getInstance().RecentlySurvivorVehicles.getValue() == 3) {
                    _byte = 30;
                }

                if (zombie.SandboxOptions.getInstance().RecentlySurvivorVehicles.getValue() == 4) {
                    _byte = 50;
                }

                if (Rand.Next(100) < _byte) {
                    this.setGoodCar(true);
                }
            }

            this.createParts();
            this.initParts();
            if (!this.createdModel) {
                ModelManager.instance.addVehicle(this);
                this.createdModel = true;
            }

            this.updateTransform();
            this.lights.clear();

            for (int _int = 0; _int < this.parts.size(); _int++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                if (vehiclePart.getLight() != null) {
                    this.lights.add(vehiclePart);
                }
            }

            this.setMaxSpeed(this.getScript().maxSpeed);
            this.setInitialMass(this.getScript().getMass());
            if (!this.getCell().getVehicles().contains(this) && !this.getCell().addVehicles.contains(this)) {
                this.getCell().addVehicles.add(this);
            }

            this.square = this.getCell().getGridSquare((double)this.x, (double)this.y, (double)this.z);
            this.randomizeContainers();
            if (this.engineState == BaseVehicle.engineStateTypes.Running) {
                this.engineDoRunning();
            }

            this.updateTotalMass();
            this.bDoDamageOverlay = true;
            this.updatePartStats();
            this.mechanicalID = Rand.Next(100000);
        }
    }

    public boolean isPreviouslyEntered() {
        return this.previouslyEntered;
    }

    public void setPreviouslyEntered(boolean _boolean) {
        this.previouslyEntered = _boolean;
    }

    @Override
    public int getKeyId() {
        return this.keyId;
    }

    public boolean getKeySpawned() {
        return this.keySpawned != 0;
    }

    public void putKeyToZombie(IsoZombie zombie) {
        if (Rand.Next(10) != 1) {
            InventoryItem inventoryItem0 = this.createVehicleKey();
            zombie.getInventory().AddItem(inventoryItem0);
        } else if (zombie.getInventory().AddItem("Base.KeyRing") instanceof InventoryContainer inventoryContainer) {
            InventoryItem inventoryItem1 = this.createVehicleKey();
            inventoryContainer.getInventory().AddItem(inventoryItem1);
        }
    }

    public void putKeyToContainer(ItemContainer container, IsoGridSquare sq, IsoObject obj) {
        InventoryItem inventoryItem = this.createVehicleKey();
        container.AddItem(inventoryItem);
        if (GameServer.bServer) {
            for (int int0 = 0; int0 < GameServer.udpEngine.connections.size(); int0++) {
                UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(int0);
                if (udpConnection.RelevantTo((float)obj.square.x, (float)obj.square.y)) {
                    ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
                    PacketTypes.PacketType.AddInventoryItemToContainer.doPacket(byteBufferWriter);
                    byteBufferWriter.putShort((short)2);
                    byteBufferWriter.putInt((int)obj.getX());
                    byteBufferWriter.putInt((int)obj.getY());
                    byteBufferWriter.putInt((int)obj.getZ());
                    int int1 = sq.getObjects().indexOf(obj);
                    byteBufferWriter.putByte((byte)int1);
                    byteBufferWriter.putByte((byte)obj.getContainerIndex(container));

                    try {
                        CompressIdenticalItems.save(byteBufferWriter.bb, inventoryItem);
                    } catch (Exception exception) {
                        exception.printStackTrace();
                    }

                    PacketTypes.PacketType.AddInventoryItemToContainer.send(udpConnection);
                }
            }
        }
    }

    public void putKeyToWorld(IsoGridSquare sq) {
        InventoryItem inventoryItem = this.createVehicleKey();
        sq.AddWorldInventoryItem(inventoryItem, 0.0F, 0.0F, 0.0F);
    }

    public void addKeyToWorld() {
        if (this.haveOneDoorUnlocked() && Rand.Next(100) < 30) {
            if (Rand.Next(5) == 0) {
                this.keyIsOnDoor = true;
                this.currentKey = this.createVehicleKey();
            } else {
                this.addKeyToGloveBox();
            }
        } else if (this.haveOneDoorUnlocked() && Rand.Next(100) < 30) {
            this.keysInIgnition = true;
            this.currentKey = this.createVehicleKey();
        } else {
            if (Rand.Next(100) < 50) {
                IsoGridSquare isoGridSquare = this.getCell().getGridSquare((double)this.x, (double)this.y, (double)this.z);
                if (isoGridSquare != null) {
                    this.addKeyToSquare(isoGridSquare);
                    return;
                }
            }
        }
    }

    public void addKeyToGloveBox() {
        if (this.keySpawned == 0) {
            if (this.getPartById("GloveBox") != null) {
                VehiclePart vehiclePart = this.getPartById("GloveBox");
                InventoryItem inventoryItem = this.createVehicleKey();
                vehiclePart.container.addItem(inventoryItem);
                this.keySpawned = 1;
            }
        }
    }

    public InventoryItem createVehicleKey() {
        InventoryItem inventoryItem = InventoryItemFactory.CreateItem("CarKey");
        inventoryItem.setKeyId(this.getKeyId());
        inventoryItem.setName(Translator.getText("IGUI_CarKey", Translator.getText("IGUI_VehicleName" + this.getScript().getName())));
        Color color = Color.HSBtoRGB(this.colorHue, this.colorSaturation * 0.5F, this.colorValue);
        inventoryItem.setColor(color);
        inventoryItem.setCustomColor(true);
        return inventoryItem;
    }

    public boolean addKeyToSquare(IsoGridSquare sq) {
        boolean _boolean = false;
        Object object = null;

        for (int int0 = 0; int0 < 3; int0++) {
            for (int int1 = sq.getX() - 10; int1 < sq.getX() + 10; int1++) {
                for (int int2 = sq.getY() - 10; int2 < sq.getY() + 10; int2++) {
                    object = IsoWorld.instance.getCell().getGridSquare(int1, int2, int0);
                    if (object != null) {
                        for (int int3 = 0; int3 < ((IsoGridSquare)object).getObjects().size(); int3++) {
                            IsoObject isoObject = ((IsoGridSquare)object).getObjects().get(int3);
                            if (isoObject.container != null
                                && (
                                    isoObject.container.type.equals("counter")
                                        || isoObject.container.type.equals("officedrawers")
                                        || isoObject.container.type.equals("shelves")
                                        || isoObject.container.type.equals("desk")
                                )) {
                                this.putKeyToContainer(isoObject.container, (IsoGridSquare)object, isoObject);
                                _boolean = true;
                                break;
                            }
                        }

                        for (int int4 = 0; int4 < ((IsoGridSquare)object).getMovingObjects().size(); int4++) {
                            if (((IsoGridSquare)object).getMovingObjects().get(int4) instanceof IsoZombie) {
                                ((IsoZombie)((IsoGridSquare)object).getMovingObjects().get(int4)).addItemToSpawnAtDeath(this.createVehicleKey());
                                _boolean = true;
                                break;
                            }
                        }
                    }

                    if (_boolean) {
                        break;
                    }
                }

                if (_boolean) {
                    break;
                }
            }

            if (_boolean) {
                break;
            }
        }

        if (Rand.Next(10) < 6) {
            while (!_boolean) {
                int int5 = sq.getX() - 10 + Rand.Next(20);
                int int6 = sq.getY() - 10 + Rand.Next(20);
                object = IsoWorld.instance.getCell().getGridSquare((double)int5, (double)int6, (double)this.z);
                if (object != null && !((IsoGridSquare)object).isSolid() && !((IsoGridSquare)object).isSolidTrans() && !((IsoGridSquare)object).HasTree()) {
                    this.putKeyToWorld((IsoGridSquare)object);
                    _boolean = true;
                    break;
                }
            }
        }

        return _boolean;
    }

    public void toggleLockedDoor(VehiclePart part, IsoGameCharacter chr, boolean locked) {
        if (locked) {
            if (!this.canLockDoor(part, chr)) {
                return;
            }

            part.getDoor().setLocked(true);
        } else {
            if (!this.canUnlockDoor(part, chr)) {
                return;
            }

            part.getDoor().setLocked(false);
        }
    }

    public boolean canLockDoor(VehiclePart part, IsoGameCharacter chr) {
        if (part == null) {
            return false;
        } else if (chr == null) {
            return false;
        } else {
            VehicleDoor vehicleDoor = part.getDoor();
            if (vehicleDoor == null) {
                return false;
            } else if (vehicleDoor.lockBroken) {
                return false;
            } else if (vehicleDoor.locked) {
                return false;
            } else if (this.getSeat(chr) != -1) {
                return true;
            } else if (chr.getInventory().haveThisKeyId(this.getKeyId()) != null) {
                return true;
            } else {
                VehiclePart vehiclePart = part.getChildWindow();
                if (vehiclePart != null && vehiclePart.getInventoryItem() == null) {
                    return true;
                } else {
                    VehicleWindow vehicleWindow = vehiclePart == null ? null : vehiclePart.getWindow();
                    return vehicleWindow != null && (vehicleWindow.isOpen() || vehicleWindow.isDestroyed());
                }
            }
        }
    }

    public boolean canUnlockDoor(VehiclePart part, IsoGameCharacter chr) {
        if (part == null) {
            return false;
        } else if (chr == null) {
            return false;
        } else {
            VehicleDoor vehicleDoor = part.getDoor();
            if (vehicleDoor == null) {
                return false;
            } else if (vehicleDoor.lockBroken) {
                return false;
            } else if (!vehicleDoor.locked) {
                return false;
            } else if (this.getSeat(chr) != -1) {
                return true;
            } else if (chr.getInventory().haveThisKeyId(this.getKeyId()) != null) {
                return true;
            } else {
                VehiclePart vehiclePart = part.getChildWindow();
                if (vehiclePart != null && vehiclePart.getInventoryItem() == null) {
                    return true;
                } else {
                    VehicleWindow vehicleWindow = vehiclePart == null ? null : vehiclePart.getWindow();
                    return vehicleWindow != null && (vehicleWindow.isOpen() || vehicleWindow.isDestroyed());
                }
            }
        }
    }

    private void initParts() {
        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            String string = vehiclePart.getLuaFunction("init");
            if (string != null) {
                this.callLuaVoid(string, this, vehiclePart);
            }
        }
    }

    public void setGeneralPartCondition(float _baseQuality, float chanceToSpawnDamaged) {
        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            vehiclePart.setGeneralCondition(null, _baseQuality, chanceToSpawnDamaged);
        }
    }

    private void createParts() {
        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            ArrayList arrayList = vehiclePart.getItemType();
            if (vehiclePart.bCreated
                && arrayList != null
                && !arrayList.isEmpty()
                && vehiclePart.getInventoryItem() == null
                && vehiclePart.getTable("install") == null) {
                vehiclePart.bCreated = false;
            } else if ((arrayList == null || arrayList.isEmpty()) && vehiclePart.getInventoryItem() != null) {
                vehiclePart.item = null;
            }

            if (!vehiclePart.bCreated) {
                vehiclePart.bCreated = true;
                String string = vehiclePart.getLuaFunction("create");
                if (string == null) {
                    vehiclePart.setRandomCondition(null);
                } else {
                    this.callLuaVoid(string, this, vehiclePart);
                    if (vehiclePart.getCondition() == -1) {
                        vehiclePart.setRandomCondition(null);
                    }
                }
            }
        }

        if (this.hasLightbar() && this.getScript().rightSirenCol != null && this.getScript().leftSirenCol != null) {
            this.leftLight1.r = this.leftLight2.r = this.getScript().leftSirenCol.r;
            this.leftLight1.g = this.leftLight2.g = this.getScript().leftSirenCol.g;
            this.leftLight1.b = this.leftLight2.b = this.getScript().leftSirenCol.b;
            this.rightLight1.r = this.rightLight2.r = this.getScript().rightSirenCol.r;
            this.rightLight1.g = this.rightLight2.g = this.getScript().rightSirenCol.g;
            this.rightLight1.b = this.rightLight2.b = this.getScript().rightSirenCol.b;
        }
    }

    public CarController getController() {
        return this.physics;
    }

    public SurroundVehicle getSurroundVehicle() {
        return this.m_surroundVehicle;
    }

    public int getSkinCount() {
        return this.script.getSkinCount();
    }

    public int getSkinIndex() {
        return this.skinIndex;
    }

    public void setSkinIndex(int index) {
        if (index >= 0 && index <= this.getSkinCount()) {
            this.skinIndex = index;
        }
    }

    public void updateSkin() {
        if (this.sprite != null && this.sprite.modelSlot != null && this.sprite.modelSlot.model != null) {
            VehicleModelInstance vehicleModelInstance = (VehicleModelInstance)this.sprite.modelSlot.model;
            VehicleScript.Skin skin = this.script.getTextures();
            VehicleScript vehicleScript = this.getScript();
            if (this.getSkinIndex() >= 0 && this.getSkinIndex() < vehicleScript.getSkinCount()) {
                skin = vehicleScript.getSkin(this.getSkinIndex());
            }

            vehicleModelInstance.LoadTexture(skin.texture);
            vehicleModelInstance.tex = skin.textureData;
            vehicleModelInstance.textureMask = skin.textureDataMask;
            vehicleModelInstance.textureDamage1Overlay = skin.textureDataDamage1Overlay;
            vehicleModelInstance.textureDamage1Shell = skin.textureDataDamage1Shell;
            vehicleModelInstance.textureDamage2Overlay = skin.textureDataDamage2Overlay;
            vehicleModelInstance.textureDamage2Shell = skin.textureDataDamage2Shell;
            vehicleModelInstance.textureLights = skin.textureDataLights;
            vehicleModelInstance.textureRust = skin.textureDataRust;
            if (vehicleModelInstance.tex != null) {
                vehicleModelInstance.tex.bindAlways = true;
            } else {
                DebugLog.Animation.error("texture not found:", this.getSkin());
            }
        }
    }

    public Texture getShadowTexture() {
        if (this.getScript() != null) {
            VehicleScript.Skin skin = this.getScript().getTextures();
            if (this.getSkinIndex() >= 0 && this.getSkinIndex() < this.getScript().getSkinCount()) {
                skin = this.getScript().getSkin(this.getSkinIndex());
            }

            if (skin.textureDataShadow != null) {
                return skin.textureDataShadow;
            }
        }

        if (vehicleShadow == null) {
            int _int = 0;
            _int |= TextureID.bUseCompression ? 4 : 0;
            vehicleShadow = Texture.getSharedTexture("media/vehicleShadow.png", _int);
        }

        return vehicleShadow;
    }

    public VehicleScript getScript() {
        return this.script;
    }

    public void setScript(String name) {
        if (!StringUtils.isNullOrWhitespace(name)) {
            this.scriptName = name;
            boolean boolean0 = this.script != null;
            this.script = ScriptManager.instance.getVehicle(this.scriptName);
            if (this.script == null) {
                ArrayList arrayList0 = ScriptManager.instance.getAllVehicleScripts();
                if (!arrayList0.isEmpty()) {
                    ArrayList arrayList1 = new ArrayList();

                    for (int int0 = 0; int0 < arrayList0.size(); int0++) {
                        VehicleScript vehicleScript = (VehicleScript)arrayList0.get(int0);
                        if (vehicleScript.getWheelCount() == 0) {
                            arrayList1.add(vehicleScript);
                            arrayList0.remove(int0--);
                        }
                    }

                    boolean boolean1 = this.loaded && this.parts.isEmpty() || this.scriptName.contains("Burnt");
                    if (boolean1 && !arrayList1.isEmpty()) {
                        this.script = (VehicleScript)arrayList1.get(Rand.Next(arrayList1.size()));
                    } else if (!arrayList0.isEmpty()) {
                        this.script = (VehicleScript)arrayList0.get(Rand.Next(arrayList0.size()));
                    }

                    if (this.script != null) {
                        this.scriptName = this.script.getFullName();
                    }
                }
            }

            this.battery = null;
            this.models.clear();
            if (this.script != null) {
                this.scriptName = this.script.getFullName();
                BaseVehicle.Passenger[] passenger = this.passengers;
                this.passengers = new BaseVehicle.Passenger[this.script.getPassengerCount()];

                for (int int1 = 0; int1 < this.passengers.length; int1++) {
                    if (int1 < passenger.length) {
                        this.passengers[int1] = passenger[int1];
                    } else {
                        this.passengers[int1] = new BaseVehicle.Passenger();
                    }
                }

                ArrayList arrayList2 = new ArrayList();
                arrayList2.addAll(this.parts);
                this.parts.clear();

                for (int int2 = 0; int2 < this.script.getPartCount(); int2++) {
                    VehicleScript.Part part0 = this.script.getPart(int2);
                    VehiclePart vehiclePart0 = null;

                    for (int int3 = 0; int3 < arrayList2.size(); int3++) {
                        VehiclePart vehiclePart1 = (VehiclePart)arrayList2.get(int3);
                        if (vehiclePart1.getScriptPart() != null && part0.id.equals(vehiclePart1.getScriptPart().id)) {
                            vehiclePart0 = vehiclePart1;
                            break;
                        }

                        if (vehiclePart1.partId != null && part0.id.equals(vehiclePart1.partId)) {
                            vehiclePart0 = vehiclePart1;
                            break;
                        }
                    }

                    if (vehiclePart0 == null) {
                        vehiclePart0 = new VehiclePart(this);
                    }

                    vehiclePart0.setScriptPart(part0);
                    vehiclePart0.category = part0.category;
                    vehiclePart0.specificItem = part0.specificItem;
                    if (part0.container != null && part0.container.contentType == null) {
                        if (vehiclePart0.getItemContainer() == null) {
                            ItemContainer itemContainer = new ItemContainer(part0.id, null, this);
                            vehiclePart0.setItemContainer(itemContainer);
                            itemContainer.ID = 0;
                        }

                        vehiclePart0.getItemContainer().Capacity = part0.container.capacity;
                    } else {
                        vehiclePart0.setItemContainer(null);
                    }

                    if (part0.door == null) {
                        vehiclePart0.door = null;
                    } else if (vehiclePart0.door == null) {
                        vehiclePart0.door = new VehicleDoor(vehiclePart0);
                        vehiclePart0.door.init(part0.door);
                    }

                    if (part0.window == null) {
                        vehiclePart0.window = null;
                    } else if (vehiclePart0.window == null) {
                        vehiclePart0.window = new VehicleWindow(vehiclePart0);
                        vehiclePart0.window.init(part0.window);
                    } else {
                        vehiclePart0.window.openable = part0.window.openable;
                    }

                    vehiclePart0.parent = null;
                    if (vehiclePart0.children != null) {
                        vehiclePart0.children.clear();
                    }

                    this.parts.add(vehiclePart0);
                    if ("Battery".equals(vehiclePart0.getId())) {
                        this.battery = vehiclePart0;
                    }
                }

                for (int int4 = 0; int4 < this.script.getPartCount(); int4++) {
                    VehiclePart vehiclePart2 = (VehiclePart)this.parts.get(int4);
                    VehicleScript.Part part1 = vehiclePart2.getScriptPart();
                    if (part1.parent != null) {
                        vehiclePart2.parent = this.getPartById(part1.parent);
                        if (vehiclePart2.parent != null) {
                            vehiclePart2.parent.addChild(vehiclePart2);
                        }
                    }
                }

                if (!boolean0 && !this.loaded) {
                    this.frontEndDurability = this.rearEndDurability = 99999;
                }

                this.frontEndDurability = Math.min(this.frontEndDurability, this.script.getFrontEndHealth());
                this.rearEndDurability = Math.min(this.rearEndDurability, this.script.getRearEndHealth());
                this.currentFrontEndDurability = this.frontEndDurability;
                this.currentRearEndDurability = this.rearEndDurability;

                for (int int5 = 0; int5 < this.script.getPartCount(); int5++) {
                    VehiclePart vehiclePart3 = (VehiclePart)this.parts.get(int5);
                    vehiclePart3.setInventoryItem(vehiclePart3.item);
                }
            }

            if (!this.loaded || this.colorHue == 0.0F && this.colorSaturation == 0.0F && this.colorValue == 0.0F) {
                this.doVehicleColor();
            }

            this.m_surroundVehicle.reset();
        }
    }

    @Override
    public String getScriptName() {
        return this.scriptName;
    }

    public void setScriptName(String name) {
        assert name == null || name.contains(".");

        this.scriptName = name;
    }

    public void setScript() {
        this.setScript(this.scriptName);
    }

    public void scriptReloaded() {
        this.tempTransform2.setIdentity();
        if (this.physics != null) {
            this.getWorldTransform(this.tempTransform2);
            this.tempTransform2.basis.getUnnormalizedRotation(this.savedRot);
            this.breakConstraint(false, false);
            Bullet.removeVehicle(this.VehicleID);
            this.physics = null;
        }

        if (this.createdModel) {
            ModelManager.instance.Remove(this);
            this.createdModel = false;
        }

        this.vehicleEngineRPM = null;

        for (int int0 = 0; int0 < this.parts.size(); int0++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(int0);
            vehiclePart.setInventoryItem(null);
            vehiclePart.bCreated = false;
        }

        this.setScript(this.scriptName);
        this.createPhysics();
        if (this.script != null) {
            for (int int1 = 0; int1 < this.passengers.length; int1++) {
                BaseVehicle.Passenger passenger = this.passengers[int1];
                if (passenger != null && passenger.character != null) {
                    VehicleScript.Position position = this.getPassengerPosition(int1, "inside");
                    if (position != null) {
                        passenger.offset.set(position.offset);
                    }
                }
            }
        }

        this.polyDirty = true;
        if (this.isEngineRunning()) {
            this.engineDoShuttingDown();
            this.engineState = BaseVehicle.engineStateTypes.Idle;
        }

        if (this.addedToWorld) {
            PolygonalMap2.instance.removeVehicleFromWorld(this);
            PolygonalMap2.instance.addVehicleToWorld(this);
        }
    }

    public String getSkin() {
        if (this.script != null && this.script.getSkinCount() != 0) {
            if (this.skinIndex < 0 || this.skinIndex >= this.script.getSkinCount()) {
                this.skinIndex = Rand.Next(this.script.getSkinCount());
            }

            return this.script.getSkin(this.skinIndex).texture;
        } else {
            return "BOGUS";
        }
    }

    protected BaseVehicle.ModelInfo setModelVisible(VehiclePart vehiclePart, VehicleScript.Model model, boolean _boolean) {
        for (int _int = 0; _int < this.models.size(); _int++) {
            BaseVehicle.ModelInfo modelInfo0 = (BaseVehicle.ModelInfo)this.models.get(_int);
            if (modelInfo0.part == vehiclePart && modelInfo0.scriptModel == model) {
                if (_boolean) {
                    return modelInfo0;
                }

                if (modelInfo0.m_animPlayer != null) {
                    modelInfo0.m_animPlayer = Pool.tryRelease(modelInfo0.m_animPlayer);
                }

                this.models.remove(_int);
                if (this.createdModel) {
                    ModelManager.instance.Remove(this);
                    ModelManager.instance.addVehicle(this);
                }

                vehiclePart.updateFlags = (short)(vehiclePart.updateFlags | 64);
                this.updateFlags = (short)(this.updateFlags | 64);
                return null;
            }
        }

        if (_boolean) {
            BaseVehicle.ModelInfo modelInfo1 = new BaseVehicle.ModelInfo();
            modelInfo1.part = vehiclePart;
            modelInfo1.scriptModel = model;
            modelInfo1.modelScript = ScriptManager.instance.getModelScript(model.file);
            modelInfo1.wheelIndex = vehiclePart.getWheelIndex();
            this.models.add(modelInfo1);
            if (this.createdModel) {
                ModelManager.instance.Remove(this);
                ModelManager.instance.addVehicle(this);
            }

            vehiclePart.updateFlags = (short)(vehiclePart.updateFlags | 64);
            this.updateFlags = (short)(this.updateFlags | 64);
            return modelInfo1;
        } else {
            return null;
        }
    }

    protected BaseVehicle.ModelInfo getModelInfoForPart(VehiclePart vehiclePart) {
        for (int _int = 0; _int < this.models.size(); _int++) {
            BaseVehicle.ModelInfo modelInfo = (BaseVehicle.ModelInfo)this.models.get(_int);
            if (modelInfo.part == vehiclePart) {
                return modelInfo;
            }
        }

        return null;
    }

    protected VehicleScript.Passenger getScriptPassenger(int _int) {
        if (this.getScript() == null) {
            return null;
        } else {
            return _int >= 0 && _int < this.getScript().getPassengerCount() ? this.getScript().getPassenger(_int) : null;
        }
    }

    public int getMaxPassengers() {
        return this.passengers.length;
    }

    public boolean setPassenger(int _int, IsoGameCharacter isoGameCharacter, Vector3f vector3f) {
        if (_int >= 0 && _int < this.passengers.length) {
            if (_int == 0) {
                this.setNeedPartsUpdate(true);
            }

            this.passengers[_int].character = isoGameCharacter;
            this.passengers[_int].offset.set(vector3f);
            return true;
        } else {
            return false;
        }
    }

    public boolean clearPassenger(int seat) {
        if (seat >= 0 && seat < this.passengers.length) {
            this.passengers[seat].character = null;
            this.passengers[seat].offset.set(0.0F, 0.0F, 0.0F);
            return true;
        } else {
            return false;
        }
    }

    public BaseVehicle.Passenger getPassenger(int seat) {
        return seat >= 0 && seat < this.passengers.length ? this.passengers[seat] : null;
    }

    public IsoGameCharacter getCharacter(int seat) {
        BaseVehicle.Passenger passenger = this.getPassenger(seat);
        return passenger != null ? passenger.character : null;
    }

    public int getSeat(IsoGameCharacter chr) {
        for (int _int = 0; _int < this.getMaxPassengers(); _int++) {
            if (this.getCharacter(_int) == chr) {
                return _int;
            }
        }

        return -1;
    }

    public boolean isDriver(IsoGameCharacter chr) {
        return this.getSeat(chr) == 0;
    }

    public Vector3f getWorldPos(Vector3f vector3f1, Vector3f vector3f0, VehicleScript vehicleScript) {
        return this.getWorldPos(vector3f1.x, vector3f1.y, vector3f1.z, vector3f0, vehicleScript);
    }

    public Vector3f getWorldPos(float float0, float float1, float float2, Vector3f vector3f, VehicleScript var5) {
        Transform transform = this.getWorldTransform(this.tempTransform);
        transform.origin.set(0.0F, 0.0F, 0.0F);
        vector3f.set(float0, float1, float2);
        transform.transform(vector3f);
        float float3 = this.jniTransform.origin.x + WorldSimulation.instance.offsetX;
        float float4 = this.jniTransform.origin.z + WorldSimulation.instance.offsetY;
        float float5 = this.jniTransform.origin.y / 2.46F;
        vector3f.set(float3 + vector3f.x, float4 + vector3f.z, float5 + vector3f.y);
        return vector3f;
    }

    public Vector3f getWorldPos(Vector3f vector3f1, Vector3f vector3f0) {
        return this.getWorldPos(vector3f1.x, vector3f1.y, vector3f1.z, vector3f0, this.getScript());
    }

    public Vector3f getWorldPos(float float0, float float1, float float2, Vector3f vector3f) {
        return this.getWorldPos(float0, float1, float2, vector3f, this.getScript());
    }

    public Vector3f getLocalPos(Vector3f vector3f1, Vector3f vector3f0) {
        return this.getLocalPos(vector3f1.x, vector3f1.y, vector3f1.z, vector3f0);
    }

    public Vector3f getLocalPos(float float1, float float0, float var3, Vector3f vector3f) {
        Transform transform = this.getWorldTransform(this.tempTransform);
        transform.inverse();
        vector3f.set(float1 - WorldSimulation.instance.offsetX, 0.0F, float0 - WorldSimulation.instance.offsetY);
        transform.transform(vector3f);
        return vector3f;
    }

    public Vector3f getPassengerLocalPos(int _int, Vector3f vector3f) {
        BaseVehicle.Passenger passenger = this.getPassenger(_int);
        return passenger == null ? null : vector3f.set(this.script.getModel().getOffset()).add(passenger.offset);
    }

    public Vector3f getPassengerWorldPos(int _int, Vector3f vector3f) {
        BaseVehicle.Passenger passenger = this.getPassenger(_int);
        return passenger == null ? null : this.getPassengerPositionWorldPos(passenger.offset.x, passenger.offset.y, passenger.offset.z, vector3f);
    }

    public Vector3f getPassengerPositionWorldPos(VehicleScript.Position position, Vector3f vector3f) {
        return this.getPassengerPositionWorldPos(position.offset.x, position.offset.y, position.offset.z, vector3f);
    }

    public Vector3f getPassengerPositionWorldPos(float float0, float float1, float float2, Vector3f vector3f) {
        vector3f.set(this.script.getModel().offset);
        vector3f.add(float0, float1, float2);
        this.getWorldPos(vector3f.x, vector3f.y, vector3f.z, vector3f);
        vector3f.z = (float)((int)this.getZ());
        return vector3f;
    }

    public VehicleScript.Anim getPassengerAnim(int seat, String id) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        if (passenger == null) {
            return null;
        } else {
            for (int _int = 0; _int < passenger.anims.size(); _int++) {
                VehicleScript.Anim anim = (VehicleScript.Anim)passenger.anims.get(_int);
                if (id.equals(anim.id)) {
                    return anim;
                }
            }

            return null;
        }
    }

    public VehicleScript.Position getPassengerPosition(int seat, String id) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? null : passenger.getPositionById(id);
    }

    public VehiclePart getPassengerDoor(int seat) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? null : this.getPartById(passenger.door);
    }

    public VehiclePart getPassengerDoor2(int seat) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? null : this.getPartById(passenger.door2);
    }

    public boolean isPositionOnLeftOrRight(float x, float y) {
        Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        this.getLocalPos(x, y, 0.0F, vector3f0);
        x = vector3f0.x;
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
        Vector3f vector3f1 = this.script.getExtents();
        Vector3f vector3f2 = this.script.getCenterOfMassOffset();
        float float0 = vector3f2.x - vector3f1.x / 2.0F;
        float float1 = vector3f2.x + vector3f1.x / 2.0F;
        return x < float0 * 0.98F || x > float1 * 0.98F;
    }

    public boolean haveOneDoorUnlocked() {
        for (int _int = 0; _int < this.getPartCount(); _int++) {
            VehiclePart vehiclePart = this.getPartByIndex(_int);
            if (vehiclePart.getDoor() != null
                && (vehiclePart.getId().contains("Left") || vehiclePart.getId().contains("Right"))
                && (!vehiclePart.getDoor().isLocked() || vehiclePart.getDoor().isOpen())) {
                return true;
            }
        }

        return false;
    }

    public String getPassengerArea(int seat) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? null : passenger.area;
    }

    public void playPassengerAnim(int seat, String animId) {
        IsoGameCharacter isoGameCharacter = this.getCharacter(seat);
        this.playPassengerAnim(seat, animId, isoGameCharacter);
    }

    public void playPassengerAnim(int seat, String animId, IsoGameCharacter chr) {
        if (chr != null) {
            VehicleScript.Anim anim = this.getPassengerAnim(seat, animId);
            if (anim != null) {
                this.playCharacterAnim(chr, anim, true);
            }
        }
    }

    public void playPassengerSound(int seat, String animId) {
        VehicleScript.Anim anim = this.getPassengerAnim(seat, animId);
        if (anim != null && anim.sound != null) {
            this.playSound(anim.sound);
        }
    }

    public void playPartAnim(VehiclePart part, String animId) {
        if (this.parts.contains(part)) {
            VehicleScript.Anim anim = part.getAnimById(animId);
            if (anim != null && !StringUtils.isNullOrWhitespace(anim.anim)) {
                BaseVehicle.ModelInfo modelInfo = this.getModelInfoForPart(part);
                if (modelInfo != null) {
                    AnimationPlayer animationPlayer = modelInfo.getAnimationPlayer();
                    if (animationPlayer != null && animationPlayer.isReady()) {
                        if (animationPlayer.getMultiTrack().getIndexOfTrack(modelInfo.m_track) != -1) {
                            animationPlayer.getMultiTrack().removeTrack(modelInfo.m_track);
                        }

                        modelInfo.m_track = null;
                        SkinningData skinningData = animationPlayer.getSkinningData();
                        if (skinningData == null || skinningData.AnimationClips.containsKey(anim.anim)) {
                            AnimationTrack animationTrack = animationPlayer.play(anim.anim, anim.bLoop);
                            modelInfo.m_track = animationTrack;
                            if (animationTrack != null) {
                                animationTrack.setLayerIdx(0);
                                animationTrack.BlendDelta = 1.0F;
                                animationTrack.SpeedDelta = anim.rate;
                                animationTrack.IsPlaying = anim.bAnimate;
                                animationTrack.reverse = anim.bReverse;
                                if (!modelInfo.modelScript.boneWeights.isEmpty()) {
                                    animationTrack.setBoneWeights(modelInfo.modelScript.boneWeights);
                                    animationTrack.initBoneWeights(skinningData);
                                }

                                if (part.getWindow() != null) {
                                    animationTrack.setCurrentTimeValue(animationTrack.getDuration() * part.getWindow().getOpenDelta());
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public void playActorAnim(VehiclePart part, String animId, IsoGameCharacter chr) {
        if (chr != null) {
            if (this.parts.contains(part)) {
                VehicleScript.Anim anim = part.getAnimById("Actor" + animId);
                if (anim != null) {
                    this.playCharacterAnim(chr, anim, !"EngineDoor".equals(part.getId()));
                }
            }
        }
    }

    private void playCharacterAnim(IsoGameCharacter isoGameCharacter, VehicleScript.Anim anim, boolean _boolean) {
        isoGameCharacter.PlayAnimUnlooped(anim.anim);
        isoGameCharacter.getSpriteDef().setFrameSpeedPerFrame(anim.rate);
        isoGameCharacter.getLegsSprite().Animate = true;
        Vector3f vector3f = this.getForwardVector(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        if (anim.angle.lengthSquared() != 0.0F) {
            Matrix4f matrix4f = ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).alloc();
            matrix4f.rotationXYZ(
                (float)Math.toRadians((double)anim.angle.x), (float)Math.toRadians((double)anim.angle.y), (float)Math.toRadians((double)anim.angle.z)
            );
            vector3f.rotate(matrix4f.getNormalizedRotation(this.tempQuat4f));
            ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).release(matrix4f);
        }

        Vector2 vector2 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
        vector2.set(vector3f.x, vector3f.z);
        isoGameCharacter.DirectionFromVector(vector2);
        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
        isoGameCharacter.setForwardDirection(vector3f.x, vector3f.z);
        if (isoGameCharacter.getAnimationPlayer() != null) {
            isoGameCharacter.getAnimationPlayer().setTargetAngle(isoGameCharacter.getForwardDirection().getDirection());
            if (_boolean) {
                isoGameCharacter.getAnimationPlayer().setAngleToTarget();
            }
        }

        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
    }

    public void playPartSound(VehiclePart part, IsoPlayer player, String animId) {
        if (this.parts.contains(part)) {
            VehicleScript.Anim anim = part.getAnimById(animId);
            if (anim != null && anim.sound != null) {
                this.getEmitter().playSound(anim.sound, (IsoGameCharacter)player);
            }
        }
    }

    public void setCharacterPosition(IsoGameCharacter chr, int seat, String positionId) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        if (passenger != null) {
            VehicleScript.Position position = passenger.getPositionById(positionId);
            if (position != null) {
                if (this.getCharacter(seat) == chr) {
                    this.passengers[seat].offset.set(position.offset);
                } else {
                    Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                    if (position.area == null) {
                        this.getPassengerPositionWorldPos(position, vector3f);
                    } else {
                        VehicleScript.Area area = this.script.getAreaById(position.area);
                        Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                        Vector2 vector21 = this.areaPositionWorld4PlayerInteract(area, vector20);
                        vector3f.x = vector21.x;
                        vector3f.y = vector21.y;
                        vector3f.z = 0.0F;
                        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                    }

                    chr.setX(vector3f.x);
                    chr.setY(vector3f.y);
                    chr.setZ(0.0F);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
                }

                if (chr instanceof IsoPlayer && ((IsoPlayer)chr).isLocalPlayer()) {
                    ((IsoPlayer)chr).dirtyRecalcGridStackTime = 10.0F;
                }
            }
        }
    }

    public void transmitCharacterPosition(int seat, String positionId) {
        if (GameClient.bClient) {
            VehicleManager.instance.sendPassengerPosition(this, seat, positionId);
        }
    }

    public void setCharacterPositionToAnim(IsoGameCharacter chr, int seat, String animId) {
        VehicleScript.Anim anim = this.getPassengerAnim(seat, animId);
        if (anim != null) {
            if (this.getCharacter(seat) == chr) {
                this.passengers[seat].offset.set(anim.offset);
            } else {
                Vector3f vector3f = this.getWorldPos(anim.offset, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                chr.setX(vector3f.x);
                chr.setY(vector3f.y);
                chr.setZ(0.0F);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            }
        }
    }

    public int getPassengerSwitchSeatCount(int seat) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? -1 : passenger.switchSeats.size();
    }

    public VehicleScript.Passenger.SwitchSeat getPassengerSwitchSeat(int seat, int index) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        if (passenger == null) {
            return null;
        } else {
            return index >= 0 && index < passenger.switchSeats.size() ? (VehicleScript.Passenger.SwitchSeat)passenger.switchSeats.get(index) : null;
        }
    }

    private VehicleScript.Passenger.SwitchSeat getSwitchSeat(int int0, int int2) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(int0);
        if (passenger == null) {
            return null;
        } else {
            for (int int1 = 0; int1 < passenger.switchSeats.size(); int1++) {
                VehicleScript.Passenger.SwitchSeat switchSeat = (VehicleScript.Passenger.SwitchSeat)passenger.switchSeats.get(int1);
                if (switchSeat.seat == int2 && this.getPartForSeatContainer(int2) != null && this.getPartForSeatContainer(int2).getInventoryItem() != null) {
                    return switchSeat;
                }
            }

            return null;
        }
    }

    public String getSwitchSeatAnimName(int seatFrom, int seatTo) {
        VehicleScript.Passenger.SwitchSeat switchSeat = this.getSwitchSeat(seatFrom, seatTo);
        return switchSeat == null ? null : switchSeat.anim;
    }

    public float getSwitchSeatAnimRate(int seatFrom, int seatTo) {
        VehicleScript.Passenger.SwitchSeat switchSeat = this.getSwitchSeat(seatFrom, seatTo);
        return switchSeat == null ? 0.0F : switchSeat.rate;
    }

    public String getSwitchSeatSound(int seatFrom, int seatTo) {
        VehicleScript.Passenger.SwitchSeat switchSeat = this.getSwitchSeat(seatFrom, seatTo);
        return switchSeat == null ? null : switchSeat.sound;
    }

    public boolean canSwitchSeat(int seatFrom, int seatTo) {
        VehicleScript.Passenger.SwitchSeat switchSeat = this.getSwitchSeat(seatFrom, seatTo);
        return switchSeat != null;
    }

    public void switchSeat(IsoGameCharacter chr, int seatTo) {
        int _int = this.getSeat(chr);
        if (_int != -1) {
            this.clearPassenger(_int);
            VehicleScript.Position position = this.getPassengerPosition(seatTo, "inside");
            if (position == null) {
                Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                vector3f.set(0.0F, 0.0F, 0.0F);
                this.setPassenger(seatTo, chr, vector3f);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            } else {
                this.setPassenger(seatTo, chr, position.offset);
            }
        }
    }

    public void playSwitchSeatAnim(int seatFrom, int seatTo) {
        IsoGameCharacter isoGameCharacter = this.getCharacter(seatFrom);
        if (isoGameCharacter != null) {
            VehicleScript.Passenger.SwitchSeat switchSeat = this.getSwitchSeat(seatFrom, seatTo);
            if (switchSeat != null) {
                isoGameCharacter.PlayAnimUnlooped(switchSeat.anim);
                isoGameCharacter.getSpriteDef().setFrameSpeedPerFrame(switchSeat.rate);
                isoGameCharacter.getLegsSprite().Animate = true;
            }
        }
    }

    public boolean isSeatOccupied(int seat) {
        VehiclePart vehiclePart = this.getPartForSeatContainer(seat);
        return vehiclePart != null && vehiclePart.getItemContainer() != null && !vehiclePart.getItemContainer().getItems().isEmpty()
            ? true
            : this.getCharacter(seat) != null;
    }

    public boolean isSeatInstalled(int seat) {
        VehiclePart vehiclePart = this.getPartForSeatContainer(seat);
        return vehiclePart != null && vehiclePart.getInventoryItem() != null;
    }

    public int getBestSeat(IsoGameCharacter chr) {
        if ((int)this.getZ() != (int)chr.getZ()) {
            return -1;
        } else if (chr.DistTo(this) > 5.0F) {
            return -1;
        } else {
            VehicleScript vehicleScript = this.getScript();
            if (vehicleScript == null) {
                return -1;
            } else {
                Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                Vector2 vector2 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();

                for (int _int = 0; _int < vehicleScript.getPassengerCount(); _int++) {
                    if (!this.isEnterBlocked(chr, _int) && !this.isSeatOccupied(_int)) {
                        VehicleScript.Position position = this.getPassengerPosition(_int, "outside");
                        if (position != null) {
                            this.getPassengerPositionWorldPos(position, vector3f0);
                            float float0 = vector3f0.x;
                            float float1 = vector3f0.y;
                            this.getPassengerPositionWorldPos(0.0F, position.offset.y, position.offset.z, vector3f1);
                            vector2.set(vector3f1.x - chr.getX(), vector3f1.y - chr.getY());
                            vector2.normalize();
                            float float2 = vector2.dot(chr.getForwardDirection());
                            if (float2 > 0.5F && IsoUtils.DistanceTo(chr.getX(), chr.getY(), float0, float1) < 1.0F) {
                                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                                ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
                                return _int;
                            }
                        }

                        position = this.getPassengerPosition(_int, "outside2");
                        if (position != null) {
                            this.getPassengerPositionWorldPos(position, vector3f0);
                            float float3 = vector3f0.x;
                            float float4 = vector3f0.y;
                            this.getPassengerPositionWorldPos(0.0F, position.offset.y, position.offset.z, vector3f1);
                            vector2.set(vector3f1.x - chr.getX(), vector3f1.y - chr.getY());
                            vector2.normalize();
                            float float5 = vector2.dot(chr.getForwardDirection());
                            if (float5 > 0.5F && IsoUtils.DistanceTo(chr.getX(), chr.getY(), float3, float4) < 1.0F) {
                                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                                ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
                                return _int;
                            }
                        }
                    }
                }

                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
                return -1;
            }
        }
    }

    public void updateHasExtendOffsetForExit(IsoGameCharacter chr) {
        this.hasExtendOffsetExiting = true;
        this.updateHasExtendOffset(chr);
        this.getPoly();
    }

    public void updateHasExtendOffsetForExitEnd(IsoGameCharacter chr) {
        this.hasExtendOffsetExiting = false;
        this.updateHasExtendOffset(chr);
        this.getPoly();
    }

    public void updateHasExtendOffset(IsoGameCharacter chr) {
        this.hasExtendOffset = false;
        this.hasExtendOffsetExiting = false;
    }

    public VehiclePart getUseablePart(IsoGameCharacter chr) {
        return this.getUseablePart(chr, true);
    }

    public VehiclePart getUseablePart(IsoGameCharacter chr, boolean checkDir) {
        if (chr.getVehicle() != null) {
            return null;
        } else if ((int)this.getZ() != (int)chr.getZ()) {
            return null;
        } else if (chr.DistTo(this) > 6.0F) {
            return null;
        } else {
            VehicleScript vehicleScript = this.getScript();
            if (vehicleScript == null) {
                return null;
            } else {
                Vector3f vector3f0 = vehicleScript.getExtents();
                Vector3f vector3f1 = vehicleScript.getCenterOfMassOffset();
                float float0 = vector3f1.z - vector3f0.z / 2.0F;
                float float1 = vector3f1.z + vector3f0.z / 2.0F;
                Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();

                for (int _int = 0; _int < this.parts.size(); _int++) {
                    VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                    if (vehiclePart.getArea() != null && this.isInArea(vehiclePart.getArea(), chr)) {
                        String string = vehiclePart.getLuaFunction("use");
                        if (string != null && !string.equals("")) {
                            VehicleScript.Area area = vehicleScript.getAreaById(vehiclePart.getArea());
                            if (area != null) {
                                Vector2 vector21 = this.areaPositionLocal(area, vector20);
                                if (vector21 != null) {
                                    float float2 = 0.0F;
                                    float float3 = 0.0F;
                                    float float4 = 0.0F;
                                    if (!(vector21.y >= float1) && !(vector21.y <= float0)) {
                                        float4 = vector21.y;
                                    } else {
                                        float2 = vector21.x;
                                    }

                                    if (!checkDir) {
                                        return vehiclePart;
                                    }

                                    this.getWorldPos(float2, float3, float4, vector3f2);
                                    vector20.set(vector3f2.x - chr.getX(), vector3f2.y - chr.getY());
                                    vector20.normalize();
                                    float float5 = vector20.dot(chr.getForwardDirection());
                                    if (float5 > 0.5F
                                        && !PolygonalMap2.instance.lineClearCollide(chr.x, chr.y, vector3f2.x, vector3f2.y, (int)chr.z, this, false, true)) {
                                        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                                        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                                        return vehiclePart;
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                return null;
            }
        }
    }

    public VehiclePart getClosestWindow(IsoGameCharacter chr) {
        if ((int)this.getZ() != (int)chr.getZ()) {
            return null;
        } else if (chr.DistTo(this) > 5.0F) {
            return null;
        } else {
            Vector3f vector3f0 = this.script.getExtents();
            Vector3f vector3f1 = this.script.getCenterOfMassOffset();
            float float0 = vector3f1.z - vector3f0.z / 2.0F;
            float float1 = vector3f1.z + vector3f0.z / 2.0F;
            Vector2 vector2 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
            Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();

            for (int _int = 0; _int < this.parts.size(); _int++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                if (vehiclePart.getWindow() != null && vehiclePart.getArea() != null && this.isInArea(vehiclePart.getArea(), chr)) {
                    VehicleScript.Area area = this.script.getAreaById(vehiclePart.getArea());
                    if (!(area.y >= float1) && !(area.y <= float0)) {
                        vector3f2.set(0.0F, 0.0F, area.y);
                    } else {
                        vector3f2.set(area.x, 0.0F, 0.0F);
                    }

                    this.getWorldPos(vector3f2, vector3f2);
                    vector2.set(vector3f2.x - chr.getX(), vector3f2.y - chr.getY());
                    vector2.normalize();
                    float float2 = vector2.dot(chr.getForwardDirection());
                    if (float2 > 0.5F) {
                        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
                        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                        return vehiclePart;
                    }
                    break;
                }
            }

            ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
            return null;
        }
    }

    public void getFacingPosition(IsoGameCharacter chr, Vector2 out) {
        Vector3f vector3f0 = this.getLocalPos(chr.getX(), chr.getY(), chr.getZ(), ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        Vector3f vector3f1 = this.script.getExtents();
        Vector3f vector3f2 = this.script.getCenterOfMassOffset();
        float float0 = vector3f2.x - vector3f1.x / 2.0F;
        float float1 = vector3f2.x + vector3f1.x / 2.0F;
        float float2 = vector3f2.z - vector3f1.z / 2.0F;
        float float3 = vector3f2.z + vector3f1.z / 2.0F;
        float float4 = 0.0F;
        float float5 = 0.0F;
        if (vector3f0.x <= 0.0F && vector3f0.z >= float2 && vector3f0.z <= float3) {
            float5 = vector3f0.z;
        } else if (vector3f0.x > 0.0F && vector3f0.z >= float2 && vector3f0.z <= float3) {
            float5 = vector3f0.z;
        } else if (vector3f0.z <= 0.0F && vector3f0.x >= float0 && vector3f0.x <= float1) {
            float4 = vector3f0.x;
        } else if (vector3f0.z > 0.0F && vector3f0.x >= float0 && vector3f0.x <= float1) {
            float4 = vector3f0.x;
        }

        this.getWorldPos(float4, 0.0F, float5, vector3f0);
        out.set(vector3f0.x, vector3f0.y);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
    }

    public boolean enter(int _int, IsoGameCharacter isoGameCharacter, Vector3f vector3f) {
        if (!GameClient.bClient) {
            VehiclesDB2.instance.updateVehicleAndTrailer(this);
        }

        if (isoGameCharacter == null) {
            return false;
        } else if (isoGameCharacter.getVehicle() != null && !isoGameCharacter.getVehicle().exit(isoGameCharacter)) {
            return false;
        } else if (this.setPassenger(_int, isoGameCharacter, vector3f)) {
            isoGameCharacter.setVehicle(this);
            isoGameCharacter.setCollidable(false);
            if (GameClient.bClient) {
                VehicleManager.instance.sendEnter(GameClient.connection, this, isoGameCharacter, _int);
            }

            if (isoGameCharacter instanceof IsoPlayer && ((IsoPlayer)isoGameCharacter).isLocalPlayer()) {
                ((IsoPlayer)isoGameCharacter).dirtyRecalcGridStackTime = 10.0F;
            }

            return true;
        } else {
            return false;
        }
    }

    public boolean enter(int seat, IsoGameCharacter chr) {
        if (this.getPartForSeatContainer(seat) != null && this.getPartForSeatContainer(seat).getInventoryItem() != null) {
            VehicleScript.Position position = this.getPassengerPosition(seat, "outside");
            return position != null ? this.enter(seat, chr, position.offset) : false;
        } else {
            return false;
        }
    }

    public boolean enterRSync(int seat, IsoGameCharacter chr, BaseVehicle v) {
        if (chr == null) {
            return false;
        } else {
            VehicleScript.Position position = this.getPassengerPosition(seat, "inside");
            if (position != null) {
                if (this.setPassenger(seat, chr, position.offset)) {
                    chr.setVehicle(v);
                    chr.setCollidable(false);
                    if (GameClient.bClient) {
                        LuaEventManager.triggerEvent("OnContainerUpdate");
                    }

                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }

    public boolean exit(IsoGameCharacter chr) {
        if (!GameClient.bClient) {
            VehiclesDB2.instance.updateVehicleAndTrailer(this);
        }

        if (chr == null) {
            return false;
        } else {
            int _int = this.getSeat(chr);
            if (_int == -1) {
                return false;
            } else if (this.clearPassenger(_int)) {
                this.enginePower = (int)this.getScript().getEngineForce();
                chr.setVehicle(null);
                chr.savedVehicleSeat = -1;
                chr.setCollidable(true);
                if (GameClient.bClient) {
                    VehicleManager.instance.sendExit(GameClient.connection, this, chr, _int);
                }

                if (this.getDriver() == null && this.soundHornOn) {
                    this.onHornStop();
                }

                this.polyGarageCheck = true;
                this.polyDirty = true;
                return true;
            } else {
                return false;
            }
        }
    }

    public boolean exitRSync(IsoGameCharacter chr) {
        if (chr == null) {
            return false;
        } else {
            int _int = this.getSeat(chr);
            if (_int == -1) {
                return false;
            } else if (this.clearPassenger(_int)) {
                chr.setVehicle(null);
                chr.setCollidable(true);
                if (GameClient.bClient) {
                    LuaEventManager.triggerEvent("OnContainerUpdate");
                }

                return true;
            } else {
                return false;
            }
        }
    }

    public boolean hasRoof(int seat) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? false : passenger.hasRoof;
    }

    public boolean showPassenger(int seat) {
        VehicleScript.Passenger passenger = this.getScriptPassenger(seat);
        return passenger == null ? false : passenger.showPassenger;
    }

    public boolean showPassenger(IsoGameCharacter chr) {
        int _int = this.getSeat(chr);
        return this.showPassenger(_int);
    }

    @Override
    public void save(ByteBuffer output, boolean IS_DEBUG_SAVE) throws IOException {
        if (this.square != null) {
            float _float = 5.0E-4F;
            this.x = PZMath.clamp(this.x, (float)this.square.x + _float, (float)(this.square.x + 1) - _float);
            this.y = PZMath.clamp(this.y, (float)this.square.y + _float, (float)(this.square.y + 1) - _float);
        }

        super.save(output, IS_DEBUG_SAVE);
        Quaternionf quaternionf = this.savedRot;
        Transform transform = this.getWorldTransform(this.tempTransform);
        output.putFloat(transform.origin.y);
        transform.getRotation(quaternionf);
        output.putFloat(quaternionf.x);
        output.putFloat(quaternionf.y);
        output.putFloat(quaternionf.z);
        output.putFloat(quaternionf.w);
        zombie.GameWindow.WriteStringUTF(output, this.scriptName);
        output.putInt(this.skinIndex);
        output.put((byte)(this.isEngineRunning() ? 1 : 0));
        output.putInt(this.frontEndDurability);
        output.putInt(this.rearEndDurability);
        output.putInt(this.currentFrontEndDurability);
        output.putInt(this.currentRearEndDurability);
        output.putInt(this.engineLoudness);
        output.putInt(this.engineQuality);
        output.putInt(this.keyId);
        output.put(this.keySpawned);
        output.put((byte)(this.headlightsOn ? 1 : 0));
        output.put((byte)(this.bCreated ? 1 : 0));
        output.put((byte)(this.soundHornOn ? 1 : 0));
        output.put((byte)(this.soundBackMoveOn ? 1 : 0));
        output.put((byte)this.lightbarLightsMode.get());
        output.put((byte)this.lightbarSirenMode.get());
        output.putShort((short)this.parts.size());

        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            vehiclePart.save(output);
        }

        output.put((byte)(this.keyIsOnDoor ? 1 : 0));
        output.put((byte)(this.hotwired ? 1 : 0));
        output.put((byte)(this.hotwiredBroken ? 1 : 0));
        output.put((byte)(this.keysInIgnition ? 1 : 0));
        output.putFloat(this.rust);
        output.putFloat(this.colorHue);
        output.putFloat(this.colorSaturation);
        output.putFloat(this.colorValue);
        output.putInt(this.enginePower);
        output.putShort(this.VehicleID);
        zombie.GameWindow.WriteString(output, null);
        output.putInt(this.mechanicalID);
        output.put((byte)(this.alarmed ? 1 : 0));
        output.putDouble(this.sirenStartTime);
        if (this.getCurrentKey() != null) {
            output.put((byte)1);
            this.getCurrentKey().saveWithSize(output, false);
        } else {
            output.put((byte)0);
        }

        output.put((byte)this.bloodIntensity.size());

        for (Entry entry : this.bloodIntensity.entrySet()) {
            zombie.GameWindow.WriteStringUTF(output, (String)entry.getKey());
            output.put((Byte)entry.getValue());
        }

        if (this.vehicleTowingID != -1) {
            output.put((byte)1);
            output.putInt(this.vehicleTowingID);
            zombie.GameWindow.WriteStringUTF(output, this.towAttachmentSelf);
            zombie.GameWindow.WriteStringUTF(output, this.towAttachmentOther);
            output.putFloat(this.towConstraintZOffset);
        } else {
            output.put((byte)0);
        }

        output.putFloat(this.getRegulatorSpeed());
        output.put((byte)(this.previouslyEntered ? 1 : 0));
    }

    @Override
    public void load(ByteBuffer input, int WorldVersion, boolean IS_DEBUG_SAVE) throws IOException {
        super.load(input, WorldVersion, IS_DEBUG_SAVE);
        if (this.z < 0.0F) {
            this.z = 0.0F;
        }

        if (WorldVersion >= 173) {
            this.savedPhysicsZ = PZMath.clamp(input.getFloat(), 0.0F, (float)((int)this.z) + 2.4477F);
        }

        float float0 = input.getFloat();
        float float1 = input.getFloat();
        float float2 = input.getFloat();
        float float3 = input.getFloat();
        this.savedRot.set(float0, float1, float2, float3);
        this.jniTransform
            .origin
            .set(
                this.getX() - WorldSimulation.instance.offsetX,
                Float.isNaN(this.savedPhysicsZ) ? this.z : this.savedPhysicsZ,
                this.getY() - WorldSimulation.instance.offsetY
            );
        this.jniTransform.setRotation(this.savedRot);
        this.scriptName = zombie.GameWindow.ReadStringUTF(input);
        this.skinIndex = input.getInt();
        boolean _boolean = input.get() == 1;
        if (_boolean) {
            this.engineState = BaseVehicle.engineStateTypes.Running;
        }

        this.frontEndDurability = input.getInt();
        this.rearEndDurability = input.getInt();
        this.currentFrontEndDurability = input.getInt();
        this.currentRearEndDurability = input.getInt();
        this.engineLoudness = input.getInt();
        this.engineQuality = input.getInt();
        this.engineQuality = PZMath.clamp(this.engineQuality, 0, 100);
        this.keyId = input.getInt();
        this.keySpawned = input.get();
        this.headlightsOn = input.get() == 1;
        this.bCreated = input.get() == 1;
        this.soundHornOn = input.get() == 1;
        this.soundBackMoveOn = input.get() == 1;
        this.lightbarLightsMode.set(input.get());
        this.lightbarSirenMode.set(input.get());
        short _short = input.getShort();

        for (int int0 = 0; int0 < _short; int0++) {
            VehiclePart vehiclePart = new VehiclePart(this);
            vehiclePart.load(input, WorldVersion);
            this.parts.add(vehiclePart);
        }

        if (WorldVersion >= 112) {
            this.keyIsOnDoor = input.get() == 1;
            this.hotwired = input.get() == 1;
            this.hotwiredBroken = input.get() == 1;
            this.keysInIgnition = input.get() == 1;
        }

        if (WorldVersion >= 116) {
            this.rust = input.getFloat();
            this.colorHue = input.getFloat();
            this.colorSaturation = input.getFloat();
            this.colorValue = input.getFloat();
        }

        if (WorldVersion >= 117) {
            this.enginePower = input.getInt();
        }

        if (WorldVersion >= 120) {
            input.getShort();
        }

        if (WorldVersion >= 122) {
            String string0 = zombie.GameWindow.ReadString(input);
            this.mechanicalID = input.getInt();
        }

        if (WorldVersion >= 124) {
            this.alarmed = input.get() == 1;
        }

        if (WorldVersion >= 129) {
            this.sirenStartTime = input.getDouble();
        }

        if (WorldVersion >= 133 && input.get() == 1) {
            InventoryItem inventoryItem = null;

            try {
                inventoryItem = InventoryItem.loadItem(input, WorldVersion);
            } catch (Exception exception) {
                exception.printStackTrace();
            }

            if (inventoryItem != null) {
                this.setCurrentKey(inventoryItem);
            }
        }

        if (WorldVersion >= 165) {
            byte byte0 = input.get();

            for (int int1 = 0; int1 < byte0; int1++) {
                String string1 = zombie.GameWindow.ReadStringUTF(input);
                byte byte1 = input.get();
                this.bloodIntensity.put(string1, byte1);
            }
        }

        if (WorldVersion >= 174) {
            if (input.get() == 1) {
                this.vehicleTowingID = input.getInt();
                this.towAttachmentSelf = zombie.GameWindow.ReadStringUTF(input);
                this.towAttachmentOther = zombie.GameWindow.ReadStringUTF(input);
                this.towConstraintZOffset = input.getFloat();
            }
        } else if (WorldVersion >= 172) {
            this.vehicleTowingID = input.getInt();
        }

        if (WorldVersion >= 188) {
            this.setRegulatorSpeed(input.getFloat());
        }

        if (WorldVersion >= 195) {
            this.previouslyEntered = input.get() == 1;
        }

        this.loaded = true;
    }

    @Override
    public void softReset() {
        this.keySpawned = 0;
        this.keyIsOnDoor = false;
        this.keysInIgnition = false;
        this.currentKey = null;
        this.previouslyEntered = false;
        this.engineState = BaseVehicle.engineStateTypes.Idle;
        this.randomizeContainers();
    }

    public void trySpawnKey() {
        if (!GameClient.bClient) {
            if (this.script != null && this.script.getPartById("Engine") != null) {
                if (this.keySpawned != 1) {
                    if (zombie.SandboxOptions.getInstance().VehicleEasyUse.getValue()) {
                        this.addKeyToGloveBox();
                    } else {
                        VehicleType vehicleType = VehicleType.getTypeFromName(this.getVehicleType());
                        int _int = vehicleType == null ? 70 : vehicleType.getChanceToSpawnKey();
                        if (Rand.Next(100) <= _int) {
                            this.addKeyToWorld();
                        }

                        this.keySpawned = 1;
                    }
                }
            }
        }
    }

    public boolean shouldCollideWithCharacters() {
        if (this.vehicleTowedBy != null) {
            return this.vehicleTowedBy.shouldCollideWithCharacters();
        } else {
            float _float = this.getSpeed2D();
            return this.isEngineRunning() ? _float > 0.05F : _float > 1.0F;
        }
    }

    public boolean shouldCollideWithObjects() {
        return this.vehicleTowedBy != null ? this.vehicleTowedBy.shouldCollideWithObjects() : this.isEngineRunning();
    }

    public void brekingObjects() {
        boolean boolean0 = this.shouldCollideWithCharacters();
        boolean boolean1 = this.shouldCollideWithObjects();
        if (boolean0 || boolean1) {
            Vector3f vector3f = this.script.getExtents();
            Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
            float float0 = Math.max(vector3f.x / 2.0F, vector3f.z / 2.0F) + 0.3F + 1.0F;
            int int0 = (int)Math.ceil((double)float0);

            for (int int1 = -int0; int1 < int0; int1++) {
                for (int int2 = -int0; int2 < int0; int2++) {
                    IsoGridSquare isoGridSquare = this.getCell().getGridSquare((double)(this.x + (float)int2), (double)(this.y + (float)int1), (double)this.z);
                    if (isoGridSquare != null) {
                        if (boolean1) {
                            for (int int3 = 0; int3 < isoGridSquare.getObjects().size(); int3++) {
                                IsoObject isoObject0 = isoGridSquare.getObjects().get(int3);
                                if (!(isoObject0 instanceof IsoWorldInventoryObject)) {
                                    Vector2 vector21 = null;
                                    if (!this.brekingObjectsList.contains(isoObject0) && isoObject0 != null && isoObject0.getProperties() != null) {
                                        if (isoObject0.getProperties().Is("CarSlowFactor")) {
                                            vector21 = this.testCollisionWithObject(isoObject0, 0.3F, vector20);
                                        }

                                        if (vector21 != null) {
                                            this.brekingObjectsList.add(isoObject0);
                                            if (!GameClient.bClient) {
                                                isoObject0.Collision(vector21, this);
                                            }
                                        }

                                        if (isoObject0.getProperties().Is("HitByCar")) {
                                            vector21 = this.testCollisionWithObject(isoObject0, 0.3F, vector20);
                                        }

                                        if (vector21 != null && !GameClient.bClient) {
                                            isoObject0.Collision(vector21, this);
                                        }

                                        this.checkCollisionWithPlant(isoGridSquare, isoObject0, vector20);
                                    }
                                }
                            }
                        }

                        if (boolean0) {
                            for (int int4 = 0; int4 < isoGridSquare.getMovingObjects().size(); int4++) {
                                IsoMovingObject isoMovingObject0 = (IsoMovingObject)isoGridSquare.getMovingObjects().get(int4);
                                IsoZombie isoZombie = Type.tryCastTo(isoMovingObject0, IsoZombie.class);
                                if (isoZombie != null) {
                                    if (isoZombie.isProne()) {
                                        this.testCollisionWithProneCharacter(isoZombie, false);
                                    }

                                    isoZombie.setVehicle4TestCollision(this);
                                }

                                if (isoMovingObject0 instanceof IsoPlayer && isoMovingObject0 != this.getDriver()) {
                                    IsoPlayer isoPlayer = (IsoPlayer)isoMovingObject0;
                                    isoPlayer.setVehicle4TestCollision(this);
                                }
                            }
                        }

                        if (boolean1) {
                            for (int int5 = 0; int5 < isoGridSquare.getStaticMovingObjects().size(); int5++) {
                                IsoMovingObject isoMovingObject1 = (IsoMovingObject)isoGridSquare.getStaticMovingObjects().get(int5);
                                IsoDeadBody isoDeadBody = Type.tryCastTo(isoMovingObject1, IsoDeadBody.class);
                                if (isoDeadBody != null) {
                                    int int6 = this.testCollisionWithCorpse(isoDeadBody, true);
                                }
                            }
                        }
                    }
                }
            }

            float float1 = -999.0F;

            for (int int7 = 0; int7 < this.brekingObjectsList.size(); int7++) {
                IsoObject isoObject1 = (IsoObject)this.brekingObjectsList.get(int7);
                Vector2 vector22 = this.testCollisionWithObject(isoObject1, 1.0F, vector20);
                if (vector22 == null || !isoObject1.getSquare().getObjects().contains(isoObject1)) {
                    this.brekingObjectsList.remove(isoObject1);
                    isoObject1.UnCollision(this);
                } else if (float1 < isoObject1.GetVehicleSlowFactor(this)) {
                    float1 = isoObject1.GetVehicleSlowFactor(this);
                }
            }

            if (float1 != -999.0F) {
                this.brekingSlowFactor = PZMath.clamp(float1, 0.0F, 34.0F);
            } else {
                this.brekingSlowFactor = 0.0F;
            }

            ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
        }
    }

    private void updateVelocityMultiplier() {
        if (this.physics != null && this.getScript() != null) {
            Vector3f vector3f = this.getLinearVelocity(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            vector3f.y = 0.0F;
            float float0 = vector3f.length();
            float float1 = 100000.0F;
            float float2 = 1.0F;
            if (this.getScript().getWheelCount() > 0) {
                if (float0 > 0.0F && float0 > 34.0F - this.brekingSlowFactor) {
                    float1 = 34.0F - this.brekingSlowFactor;
                    float2 = (34.0F - this.brekingSlowFactor) / float0;
                }
            } else if (this.getVehicleTowedBy() == null) {
                float1 = 0.0F;
                float2 = 0.1F;
            }

            Bullet.setVehicleVelocityMultiplier(this.VehicleID, float1, float2);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        }
    }

    private void playScrapePastPlantSound(IsoGridSquare isoGridSquare) {
        if (this.emitter != null && !this.emitter.isPlaying(this.soundScrapePastPlant)) {
            this.emitter.setPos((float)isoGridSquare.x + 0.5F, (float)isoGridSquare.y + 0.5F, (float)isoGridSquare.z);
            this.soundScrapePastPlant = this.emitter.playSoundImpl("VehicleScrapePastPlant", isoGridSquare);
        }
    }

    private void checkCollisionWithPlant(IsoGridSquare isoGridSquare, IsoObject isoObject, Vector2 vector21) {
        IsoTree isoTree = Type.tryCastTo(isoObject, IsoTree.class);
        if (isoTree != null || isoObject.getProperties().Is("Bush")) {
            float _float = Math.abs(this.getCurrentSpeedKmHour());
            if (!(_float <= 1.0F)) {
                Vector2 vector20 = this.testCollisionWithObject(isoObject, 0.3F, vector21);
                if (vector20 != null) {
                    if (isoTree != null && isoTree.getSize() == 1) {
                        this.ApplyImpulse4Break(isoObject, 0.025F);
                        this.playScrapePastPlantSound(isoGridSquare);
                    } else if (this.isPositionOnLeftOrRight(vector20.x, vector20.y)) {
                        this.ApplyImpulse4Break(isoObject, 0.025F);
                        this.playScrapePastPlantSound(isoGridSquare);
                    } else if (_float < 10.0F) {
                        this.ApplyImpulse4Break(isoObject, 0.025F);
                        this.playScrapePastPlantSound(isoGridSquare);
                    } else {
                        this.ApplyImpulse4Break(isoObject, 0.1F);
                        this.playScrapePastPlantSound(isoGridSquare);
                    }
                }
            }
        }
    }

    public void damageObjects(float damage) {
        if (this.isEngineRunning()) {
            Vector3f vector3f = this.script.getExtents();
            Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
            float _float = Math.max(vector3f.x / 2.0F, vector3f.z / 2.0F) + 0.3F + 1.0F;
            int int0 = (int)Math.ceil((double)_float);

            for (int int1 = -int0; int1 < int0; int1++) {
                for (int int2 = -int0; int2 < int0; int2++) {
                    IsoGridSquare isoGridSquare0 = this.getCell().getGridSquare((double)(this.x + (float)int2), (double)(this.y + (float)int1), (double)this.z);
                    if (isoGridSquare0 != null) {
                        for (int int3 = 0; int3 < isoGridSquare0.getObjects().size(); int3++) {
                            IsoObject isoObject = isoGridSquare0.getObjects().get(int3);
                            Vector2 vector21 = null;
                            if (isoObject instanceof IsoTree) {
                                vector21 = this.testCollisionWithObject(isoObject, 2.0F, vector20);
                                if (vector21 != null) {
                                    isoObject.setRenderEffect(RenderEffectType.Hit_Tree_Shudder);
                                }
                            }

                            if (vector21 == null && isoObject instanceof IsoWindow) {
                                vector21 = this.testCollisionWithObject(isoObject, 1.0F, vector20);
                            }

                            if (vector21 == null
                                && isoObject.sprite != null
                                && (isoObject.sprite.getProperties().Is("HitByCar") || isoObject.sprite.getProperties().Is("CarSlowFactor"))) {
                                vector21 = this.testCollisionWithObject(isoObject, 1.0F, vector20);
                            }

                            if (vector21 == null) {
                                IsoGridSquare isoGridSquare1 = this.getCell()
                                    .getGridSquare((double)(this.x + (float)int2), (double)(this.y + (float)int1), 1.0);
                                if (isoGridSquare1 != null && isoGridSquare1.getHasTypes().isSet(IsoObjectType.lightswitch)) {
                                    vector21 = this.testCollisionWithObject(isoObject, 1.0F, vector20);
                                }
                            }

                            if (vector21 == null) {
                                IsoGridSquare isoGridSquare2 = this.getCell()
                                    .getGridSquare((double)(this.x + (float)int2), (double)(this.y + (float)int1), 0.0);
                                if (isoGridSquare2 != null && isoGridSquare2.getHasTypes().isSet(IsoObjectType.lightswitch)) {
                                    vector21 = this.testCollisionWithObject(isoObject, 1.0F, vector20);
                                }
                            }

                            if (vector21 != null) {
                                isoObject.Hit(vector21, this, damage);
                            }
                        }
                    }
                }
            }

            ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
        }
    }

    @Override
    public void update() {
        if (this.removedFromWorld) {
            DebugLog.Vehicle.debugln("vehicle update() removedFromWorld=true id=%d", this.VehicleID);
        } else if (!this.getCell().vehicles.contains(this)) {
            DebugLog.Vehicle.debugln("vehicle update() not in cell.vehicles list id=%d x=%f y=%f %s", this.VehicleID, this.x, this.y, this);
            this.getCell().getRemoveList().add(this);
        } else {
            if (this.chunk == null) {
                DebugLog.Vehicle.debugln("vehicle update() chunk=null id=%d x=%f y=%f", this.VehicleID, this.x, this.y);
            } else if (!this.chunk.vehicles.contains(this)) {
                DebugLog.Vehicle.debugln("vehicle update() not in chunk.vehicles list id=%d x=%f y=%f", this.VehicleID, this.x, this.y);
                if (GameClient.bClient) {
                    VehicleManager.instance.sendRequestGetPosition(this.VehicleID, PacketTypes.PacketType.VehiclesUnreliable);
                }
            } else if (!GameServer.bServer && this.chunk.refs.isEmpty()) {
                DebugLog.Vehicle.debugln("vehicle update() chunk was unloaded id=%d", this.VehicleID);
                this.removeFromWorld();
                return;
            }

            super.update();
            if (GameClient.bClient || GameServer.bServer) {
                this.isReliable = this.physicReliableLimit.Check();
            }

            if (GameClient.bClient && this.hasAuthorization(GameClient.connection)) {
                this.updatePhysicsNetwork();
            }

            if (this.getVehicleTowing() != null && this.getDriver() != null) {
                float float0 = 2.5F;
                if (this.getVehicleTowing().getPartCount() == 0) {
                    float0 = 12.0F;
                }

                if (this.getVehicleTowing().scriptName.equals("Base.Trailer")) {
                    VehiclePart vehiclePart0 = this.getVehicleTowing().getPartById("TrailerTrunk");
                    if (this.getCurrentSpeedKmHour() > 30.0F && vehiclePart0.getCondition() < 50 && !vehiclePart0.container.Items.isEmpty()) {
                        ArrayList arrayList = new ArrayList();

                        for (int int0 = 0; int0 < vehiclePart0.container.Items.size(); int0++) {
                            if ((double)((InventoryItem)vehiclePart0.container.Items.get(int0)).getWeight() >= 3.5) {
                                arrayList.add((InventoryItem)vehiclePart0.container.Items.get(int0));
                            }
                        }

                        if (!arrayList.isEmpty()) {
                            int int1 = vehiclePart0.getCondition();
                            int int2 = 0;
                            int int3 = 0;

                            for (int int4 = 0; int4 < this.getVehicleTowing().parts.size(); int4++) {
                                VehiclePart vehiclePart1 = this.getVehicleTowing().getPartByIndex(int4);
                                if (vehiclePart1 != null && vehiclePart1.item != null) {
                                    if (vehiclePart1.partId != null && vehiclePart1.partId.contains("Suspension")) {
                                        int2 += vehiclePart1.getCondition();
                                    } else if (vehiclePart1.partId != null && vehiclePart1.partId.contains("Tire")) {
                                        int3 += vehiclePart1.getCondition();
                                    }
                                }
                            }

                            float float1 = this.parameterVehicleSteer.getCurrentValue();
                            int int5 = (int)(
                                Math.pow((double)(100 - int1 * 2), 2.0)
                                    * 0.3
                                    * (1.0 + (double)(100 - int2 / 2) * 0.005)
                                    * (1.0 + (double)(100 - int2 / 2) * 0.005)
                                    * (double)(1.0F + float1 / 3.0F)
                            );
                            if (Rand.Next(0, Math.max(10000 - int5, 1)) == 0) {
                                InventoryItem inventoryItem = (InventoryItem)arrayList.get(Rand.Next(0, arrayList.size()));
                                inventoryItem.setCondition(inventoryItem.getCondition() - inventoryItem.getConditionMax() / 10);
                                vehiclePart0.getSquare().AddWorldInventoryItem(inventoryItem, Rand.Next(0.0F, 0.5F), Rand.Next(0.0F, 0.5F), 0.0F);
                                vehiclePart0.container.Items.remove(inventoryItem);
                                vehiclePart0.getSquare().playSound("thumpa2");
                            }
                        }
                    }
                }
            }

            if (this.getVehicleTowedBy() != null && this.getDriver() != null) {
                float float2 = 2.5F;
                if (this.getVehicleTowedBy().getPartCount() == 0) {
                    float2 = 12.0F;
                }
            }

            if (this.physics != null && this.vehicleTowingID != -1 && this.vehicleTowing == null) {
                this.tryReconnectToTowedVehicle();
            }

            boolean boolean0 = false;
            boolean boolean1 = false;
            if (this.getVehicleTowedBy() != null && this.getVehicleTowedBy().getController() != null) {
                boolean0 = this.getVehicleTowedBy() != null && this.getVehicleTowedBy().getController().isEnable;
                boolean1 = this.getVehicleTowing() != null && this.getVehicleTowing().getDriver() != null;
            }

            if (this.physics != null) {
                boolean boolean2 = this.getDriver() != null || boolean0 || boolean1;
                long _long = System.currentTimeMillis();
                if (this.constraintChangedTime != -1L) {
                    if (this.constraintChangedTime + 3500L < _long) {
                        this.constraintChangedTime = -1L;
                        if (!boolean2 && this.physicActiveCheck < _long) {
                            this.setPhysicsActive(false);
                        }
                    }
                } else {
                    if (this.physicActiveCheck != -1L && (boolean2 || !this.physics.isEnable)) {
                        this.physicActiveCheck = -1L;
                    }

                    if (!boolean2 && this.physics.isEnable && this.physicActiveCheck != -1L && this.physicActiveCheck < _long) {
                        this.physicActiveCheck = -1L;
                        this.setPhysicsActive(false);
                    }
                }

                if (this.getVehicleTowedBy() != null && this.getScript().getWheelCount() > 0) {
                    this.physics.updateTrailer();
                } else if (this.getDriver() == null && !GameServer.bServer) {
                    this.physics.checkShouldBeActive();
                }

                this.doAlarm();
                BaseVehicle.VehicleImpulse vehicleImpulse0 = this.impulseFromServer;
                if (!GameServer.bServer && vehicleImpulse0 != null && vehicleImpulse0.enable) {
                    vehicleImpulse0.enable = false;
                    float float3 = 1.0F;
                    Bullet.applyCentralForceToVehicle(
                        this.VehicleID, vehicleImpulse0.impulse.x * float3, vehicleImpulse0.impulse.y * float3, vehicleImpulse0.impulse.z * float3
                    );
                    Vector3f vector3f0 = vehicleImpulse0.rel_pos
                        .cross(vehicleImpulse0.impulse, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                    Bullet.applyTorqueToVehicle(this.VehicleID, vector3f0.x * float3, vector3f0.y * float3, vector3f0.z * float3);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                }

                this.applyImpulseFromHitZombies();
                this.applyImpulseFromProneCharacters();
                short _short = 1000;
                if (System.currentTimeMillis() - this.engineCheckTime > (long)_short && !GameClient.bClient) {
                    this.engineCheckTime = System.currentTimeMillis();
                    if (!GameClient.bClient) {
                        if (this.engineState != BaseVehicle.engineStateTypes.Idle) {
                            int int6 = (int)((double)this.engineLoudness * this.engineSpeed / 2500.0);
                            double _double = Math.min(this.getEngineSpeed(), 2000.0);
                            int6 = (int)((double)int6 * (1.0 + _double / 4000.0));
                            int int7 = 120;
                            if (GameServer.bServer) {
                                int7 = (int)((double)int7 * ServerOptions.getInstance().CarEngineAttractionModifier.getValue());
                                int6 = (int)((double)int6 * ServerOptions.getInstance().CarEngineAttractionModifier.getValue());
                            }

                            if (Rand.Next((int)((float)int7 * zombie.GameTime.instance.getInvMultiplier())) == 0) {
                                zombie.WorldSoundManager.instance
                                    .addSoundRepeating(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), Math.max(8, int6), int6 / 40, false);
                            }

                            if (Rand.Next((int)((float)(int7 - 85) * zombie.GameTime.instance.getInvMultiplier())) == 0) {
                                zombie.WorldSoundManager.instance
                                    .addSoundRepeating(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), Math.max(8, int6 / 2), int6 / 40, false);
                            }

                            if (Rand.Next((int)((float)(int7 - 110) * zombie.GameTime.instance.getInvMultiplier())) == 0) {
                                zombie.WorldSoundManager.instance
                                    .addSoundRepeating(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), Math.max(8, int6 / 4), int6 / 40, false);
                            }

                            zombie.WorldSoundManager.instance
                                .addSoundRepeating(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), Math.max(8, int6 / 6), int6 / 40, false);
                        }

                        if (this.lightbarSirenMode.isEnable() && this.getBatteryCharge() > 0.0F) {
                            zombie.WorldSoundManager.instance.addSoundRepeating(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), 100, 60, false);
                        }
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.Running && !this.isEngineWorking()) {
                        this.shutOff();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.Running) {
                        VehiclePart vehiclePart2 = this.getPartById("Engine");
                        if (vehiclePart2 != null
                            && vehiclePart2.getCondition() < 50
                            && Rand.Next(Rand.AdjustForFramerate(vehiclePart2.getCondition() * 12)) == 0) {
                            this.shutOff();
                        }
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.Starting) {
                        this.updateEngineStarting();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.RetryingStarting && System.currentTimeMillis() - this.engineLastUpdateStateTime > 10L) {
                        this.engineDoStarting();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.StartingSuccess && System.currentTimeMillis() - this.engineLastUpdateStateTime > 500L) {
                        this.engineDoRunning();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.StartingFailed && System.currentTimeMillis() - this.engineLastUpdateStateTime > 500L) {
                        this.engineDoIdle();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.StartingFailedNoPower
                        && System.currentTimeMillis() - this.engineLastUpdateStateTime > 500L) {
                        this.engineDoIdle();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.Stalling && System.currentTimeMillis() - this.engineLastUpdateStateTime > 3000L) {
                        this.engineDoIdle();
                    }

                    if (this.engineState == BaseVehicle.engineStateTypes.ShutingDown && System.currentTimeMillis() - this.engineLastUpdateStateTime > 2000L) {
                        this.engineDoIdle();
                    }
                }

                if (this.getDriver() == null && !boolean0) {
                    this.getController().park();
                }

                this.setX(this.jniTransform.origin.x + WorldSimulation.instance.offsetX);
                this.setY(this.jniTransform.origin.z + WorldSimulation.instance.offsetY);
                this.setZ(0.0F);
                IsoGridSquare isoGridSquare = this.getCell().getGridSquare((double)this.x, (double)this.y, (double)this.z);
                if (isoGridSquare == null && !this.chunk.refs.isEmpty()) {
                    float float4 = 5.0E-4F;
                    int int8 = this.chunk.wx * 10;
                    int int9 = this.chunk.wy * 10;
                    int int10 = int8 + 10;
                    int int11 = int9 + 10;
                    float float5 = this.x;
                    float float6 = this.y;
                    this.x = Math.max(this.x, (float)int8 + float4);
                    this.x = Math.min(this.x, (float)int10 - float4);
                    this.y = Math.max(this.y, (float)int9 + float4);
                    this.y = Math.min(this.y, (float)int11 - float4);
                    this.z = 0.2F;
                    Transform transform0 = this.tempTransform;
                    Transform transform1 = this.tempTransform2;
                    this.getWorldTransform(transform0);
                    transform1.basis.set(transform0.basis);
                    transform1.origin.set(this.x - WorldSimulation.instance.offsetX, this.z, this.y - WorldSimulation.instance.offsetY);
                    this.setWorldTransform(transform1);
                    this.current = this.getCell().getGridSquare((double)this.x, (double)this.y, (double)this.z);
                    DebugLog.Vehicle.debugln("Vehicle vid=%d is moved into an unloaded area (%f;%f)", this.VehicleID, this.x, this.y);
                }

                if (this.current != null && this.current.chunk != null) {
                    if (this.current.getChunk() != this.chunk) {
                        assert this.chunk.vehicles.contains(this);

                        this.chunk.vehicles.remove(this);
                        this.chunk = this.current.getChunk();
                        if (!GameServer.bServer && this.chunk.refs.isEmpty()) {
                            DebugLog.Vehicle.debugln("BaseVehicle.update() added to unloaded chunk id=%d", this.VehicleID);
                        }

                        assert !this.chunk.vehicles.contains(this);

                        this.chunk.vehicles.add(this);
                        IsoChunk.addFromCheckedVehicles(this);
                    }
                } else {
                    boolean boolean3 = false;
                }

                this.updateTransform();
                Vector3f vector3f1 = allocVector3f().set(this.jniLinearVelocity);
                if (this.jniIsCollide && this.limitCrash.Check()) {
                    this.jniIsCollide = false;
                    this.limitCrash.Reset();
                    Vector3f vector3f2 = allocVector3f();
                    vector3f2.set(vector3f1).sub(this.lastLinearVelocity);
                    vector3f2.y = 0.0F;
                    float float7 = vector3f2.length();
                    DebugLog.Vehicle
                        .debugln(
                            "Vehicle vid=%d velocity last=%s/%f current=%s/%f delta=%f",
                            this.VehicleID,
                            this.lastLinearVelocity,
                            this.lastLinearVelocity.length(),
                            vector3f1,
                            vector3f1.length(),
                            float7
                        );
                    if (vector3f1.lengthSquared() > this.lastLinearVelocity.lengthSquared() && float7 > 6.0F) {
                        DebugLog.Vehicle.trace("Vehicle vid=%d got sharp speed increase delta=%f", this.VehicleID, float7);
                        float7 = 6.0F;
                    }

                    if (float7 > 1.0F) {
                        if (this.lastLinearVelocity.length() < 6.0F) {
                            float7 /= 3.0F;
                        }

                        DebugLog.Vehicle.trace("Vehicle vid=%d crash delta=%f", this.VehicleID, float7);
                        Vector3f vector3f3 = this.getForwardVector(allocVector3f());
                        float float8 = vector3f2.dot(vector3f3);
                        releaseVector3f(vector3f3);
                        this.crash(float7 * 3.0F, float8 < 0.0F);
                        this.damageObjects(float7 * 30.0F);
                    }

                    releaseVector3f(vector3f2);
                }

                this.lastLinearVelocity.set(vector3f1);
                releaseVector3f(vector3f1);
            }

            if (this.soundHornOn && this.hornemitter != null) {
                this.hornemitter.setPos(this.getX(), this.getY(), this.getZ());
            }

            for (int int12 = 0; int12 < this.impulseFromSquishedZombie.length; int12++) {
                BaseVehicle.VehicleImpulse vehicleImpulse1 = this.impulseFromSquishedZombie[int12];
                if (vehicleImpulse1 != null) {
                    vehicleImpulse1.enable = false;
                }
            }

            this.updateSounds();
            this.brekingObjects();
            if (this.bAddThumpWorldSound) {
                this.bAddThumpWorldSound = false;
                zombie.WorldSoundManager.instance.addSound(this, (int)this.x, (int)this.y, (int)this.z, 20, 20, true);
            }

            if (this.script.getLightbar().enable && this.lightbarLightsMode.isEnable() && this.getBatteryCharge() > 0.0F) {
                this.lightbarLightsMode.update();
            }

            this.updateWorldLights();

            for (int int13 = 0; int13 < IsoPlayer.numPlayers; int13++) {
                if (this.current == null || !this.current.lighting[int13].bCanSee()) {
                    this.setTargetAlpha(int13, 0.0F);
                }

                IsoPlayer isoPlayer = IsoPlayer.players[int13];
                if (isoPlayer != null && this.DistToSquared(isoPlayer) < 225.0F) {
                    this.setTargetAlpha(int13, 1.0F);
                }
            }

            for (int int14 = 0; int14 < this.getScript().getPassengerCount(); int14++) {
                if (this.getCharacter(int14) != null) {
                    Vector3f vector3f4 = this.getPassengerWorldPos(int14, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                    this.getCharacter(int14).setX(vector3f4.x);
                    this.getCharacter(int14).setY(vector3f4.y);
                    this.getCharacter(int14).setZ(vector3f4.z * 1.0F);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f4);
                }
            }

            VehiclePart vehiclePart3 = this.getPartById("lightbar");
            if (vehiclePart3 != null && this.lightbarLightsMode.isEnable() && vehiclePart3.getCondition() == 0 && !GameClient.bClient) {
                this.setLightbarLightsMode(0);
            }

            if (vehiclePart3 != null && this.lightbarSirenMode.isEnable() && vehiclePart3.getCondition() == 0 && !GameClient.bClient) {
                this.setLightbarSirenMode(0);
            }

            if (!this.needPartsUpdate() && !this.isMechanicUIOpen()) {
                this.drainBatteryUpdateHack();
            } else {
                this.updateParts();
            }

            if (this.engineState == BaseVehicle.engineStateTypes.Running || boolean0) {
                this.updateBulletStats();
            }

            if (this.bDoDamageOverlay) {
                this.bDoDamageOverlay = false;
                this.doDamageOverlay();
            }

            if (GameClient.bClient) {
                this.checkPhysicsValidWithServer();
            }

            VehiclePart vehiclePart4 = this.getPartById("GasTank");
            if (vehiclePart4 != null && vehiclePart4.getContainerContentAmount() > (float)vehiclePart4.getContainerCapacity()) {
                vehiclePart4.setContainerContentAmount((float)vehiclePart4.getContainerCapacity());
            }

            boolean boolean4 = false;

            for (int int15 = 0; int15 < this.getMaxPassengers(); int15++) {
                BaseVehicle.Passenger passenger = this.getPassenger(int15);
                if (passenger.character != null) {
                    boolean4 = true;
                    break;
                }
            }

            if (boolean4) {
                this.m_surroundVehicle.update();
            }

            if (!GameServer.bServer) {
                if (this.physics != null) {
                    Bullet.setVehicleMass(this.VehicleID, this.getFudgedMass());
                }

                this.updateVelocityMultiplier();
            }
        }
    }

    private void updateEngineStarting() {
        if (this.getBatteryCharge() <= 0.1F) {
            this.engineDoStartingFailedNoPower();
        } else {
            VehiclePart vehiclePart = this.getPartById("GasTank");
            if (vehiclePart != null && vehiclePart.getContainerContentAmount() <= 0.0F) {
                this.engineDoStartingFailed();
            } else {
                int _int = 0;
                float _float = ClimateManager.getInstance().getAirTemperatureForSquare(this.getSquare());
                if (this.engineQuality < 65 && _float <= 2.0F) {
                    _int = Math.min((2 - (int)_float) * 2, 30);
                }

                if (!zombie.SandboxOptions.instance.VehicleEasyUse.getValue() && this.engineQuality < 100 && Rand.Next(this.engineQuality + 50 - _int) <= 30) {
                    this.engineDoStartingFailed();
                } else {
                    if (Rand.Next(this.engineQuality) != 0) {
                        this.engineDoStartingSuccess();
                    } else {
                        this.engineDoRetryingStarting();
                    }
                }
            }
        }
    }

    private void applyImpulseFromHitZombies() {
        if (!this.impulseFromHitZombie.isEmpty()) {
            if ((!GameClient.bClient || this.hasAuthorization(GameClient.connection)) && !GameServer.bServer) {
                Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc().set(0.0F, 0.0F, 0.0F);
                Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc().set(0.0F, 0.0F, 0.0F);
                Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc().set(0.0F, 0.0F, 0.0F);
                int int0 = this.impulseFromHitZombie.size();

                for (int int1 = 0; int1 < int0; int1++) {
                    BaseVehicle.VehicleImpulse vehicleImpulse0 = (BaseVehicle.VehicleImpulse)this.impulseFromHitZombie.get(int1);
                    vector3f0.add(vehicleImpulse0.impulse);
                    vector3f1.add(vehicleImpulse0.rel_pos.cross(vehicleImpulse0.impulse, vector3f2));
                    vehicleImpulse0.release();
                    vehicleImpulse0.enable = false;
                }

                this.impulseFromHitZombie.clear();
                float float0 = 7.0F * this.getFudgedMass();
                if (vector3f0.lengthSquared() > float0 * float0) {
                    vector3f0.mul(float0 / vector3f0.length());
                }

                float float1 = 30.0F;
                Bullet.applyCentralForceToVehicle(this.VehicleID, vector3f0.x * float1, vector3f0.y * float1, vector3f0.z * float1);
                Bullet.applyTorqueToVehicle(this.VehicleID, vector3f1.x * float1, vector3f1.y * float1, vector3f1.z * float1);
                if (GameServer.bServer) {
                }

                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
            } else {
                int int2 = 0;

                for (int int3 = this.impulseFromHitZombie.size(); int2 < int3; int2++) {
                    BaseVehicle.VehicleImpulse vehicleImpulse1 = (BaseVehicle.VehicleImpulse)this.impulseFromHitZombie.get(int2);
                    vehicleImpulse1.release();
                    vehicleImpulse1.enable = false;
                }

                this.impulseFromHitZombie.clear();
            }
        }
    }

    private void applyImpulseFromProneCharacters() {
        if ((!GameClient.bClient || this.hasAuthorization(GameClient.connection)) && !GameServer.bServer) {
            boolean _boolean = PZArrayUtil.contains(this.impulseFromSquishedZombie, vehicleImpulsex -> vehicleImpulsex != null && vehicleImpulsex.enable);
            if (_boolean) {
                Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc().set(0.0F, 0.0F, 0.0F);
                Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc().set(0.0F, 0.0F, 0.0F);
                Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();

                for (int _int = 0; _int < this.impulseFromSquishedZombie.length; _int++) {
                    BaseVehicle.VehicleImpulse vehicleImpulse = this.impulseFromSquishedZombie[_int];
                    if (vehicleImpulse != null && vehicleImpulse.enable) {
                        vector3f0.add(vehicleImpulse.impulse);
                        vector3f1.add(vehicleImpulse.rel_pos.cross(vehicleImpulse.impulse, vector3f2));
                        vehicleImpulse.enable = false;
                    }
                }

                if (vector3f0.lengthSquared() > 0.0F) {
                    float float0 = this.getFudgedMass() * 0.15F;
                    if (vector3f0.lengthSquared() > float0 * float0) {
                        vector3f0.mul(float0 / vector3f0.length());
                    }

                    float float1 = 30.0F;
                    Bullet.applyCentralForceToVehicle(this.VehicleID, vector3f0.x * float1, vector3f0.y * float1, vector3f0.z * float1);
                    Bullet.applyTorqueToVehicle(this.VehicleID, vector3f1.x * float1, vector3f1.y * float1, vector3f1.z * float1);
                }

                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
            }
        }
    }

    public float getFudgedMass() {
        if (this.getScriptName().contains("Trailer")) {
            return this.getMass();
        } else {
            BaseVehicle baseVehicle1 = this.getVehicleTowedBy();
            if (baseVehicle1 != null && baseVehicle1.getDriver() != null && baseVehicle1.isEngineRunning()) {
                float _float = Math.max(250.0F, baseVehicle1.getMass() / 3.7F);
                if (this.getScript().getWheelCount() == 0) {
                    _float = Math.min(_float, 200.0F);
                }

                return _float;
            } else {
                return this.getMass();
            }
        }
    }

    private boolean isNullChunk(int int0, int int1) {
        if (!IsoWorld.instance.getMetaGrid().isValidChunk(int0, int1)) {
            return false;
        } else if (GameClient.bClient && !ClientServerMap.isChunkLoaded(int0, int1)) {
            return true;
        } else {
            return GameClient.bClient && !PassengerMap.isChunkLoaded(this, int0, int1) ? true : this.getCell().getChunk(int0, int1) == null;
        }
    }

    public boolean isInvalidChunkAround() {
        Vector3f vector3f = this.getLinearVelocity(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        float float0 = Math.abs(vector3f.x);
        float float1 = Math.abs(vector3f.z);
        boolean boolean0 = vector3f.x < 0.0F && float0 > float1;
        boolean boolean1 = vector3f.x > 0.0F && float0 > float1;
        boolean boolean2 = vector3f.z < 0.0F && float1 > float0;
        boolean boolean3 = vector3f.z > 0.0F && float1 > float0;
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return this.isInvalidChunkAround(boolean0, boolean1, boolean2, boolean3);
    }

    public boolean isInvalidChunkAhead() {
        Vector3f vector3f = this.getForwardVector(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        boolean boolean0 = vector3f.x < -0.5F;
        boolean boolean1 = vector3f.z > 0.5F;
        boolean boolean2 = vector3f.x > 0.5F;
        boolean boolean3 = vector3f.z < -0.5F;
        return this.isInvalidChunkAround(boolean0, boolean2, boolean3, boolean1);
    }

    public boolean isInvalidChunkBehind() {
        Vector3f vector3f = this.getForwardVector(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        boolean boolean0 = vector3f.x < -0.5F;
        boolean boolean1 = vector3f.z > 0.5F;
        boolean boolean2 = vector3f.x > 0.5F;
        boolean boolean3 = vector3f.z < -0.5F;
        return this.isInvalidChunkAround(boolean2, boolean0, boolean1, boolean3);
    }

    public boolean isInvalidChunkAround(boolean moveW, boolean moveE, boolean moveN, boolean moveS) {
        if (IsoChunkMap.ChunkGridWidth > 7) {
            if (moveE && (this.isNullChunk(this.chunk.wx + 1, this.chunk.wy) || this.isNullChunk(this.chunk.wx + 2, this.chunk.wy))) {
                return true;
            }

            if (moveW && (this.isNullChunk(this.chunk.wx - 1, this.chunk.wy) || this.isNullChunk(this.chunk.wx - 2, this.chunk.wy))) {
                return true;
            }

            if (moveS && (this.isNullChunk(this.chunk.wx, this.chunk.wy + 1) || this.isNullChunk(this.chunk.wx, this.chunk.wy + 2))) {
                return true;
            }

            if (moveN && (this.isNullChunk(this.chunk.wx, this.chunk.wy - 1) || this.isNullChunk(this.chunk.wx, this.chunk.wy - 2))) {
                return true;
            }
        } else {
            if (IsoChunkMap.ChunkGridWidth <= 4) {
                return false;
            }

            if (moveE && this.isNullChunk(this.chunk.wx + 1, this.chunk.wy)) {
                return true;
            }

            if (moveW && this.isNullChunk(this.chunk.wx - 1, this.chunk.wy)) {
                return true;
            }

            if (moveS && this.isNullChunk(this.chunk.wx, this.chunk.wy + 1)) {
                return true;
            }

            if (moveN && this.isNullChunk(this.chunk.wx, this.chunk.wy - 1)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public void postupdate() {
        this.current = this.getCell().getGridSquare((int)this.x, (int)this.y, 0);
        if (this.current == null) {
            for (int int0 = (int)this.z; int0 >= 0; int0--) {
                this.current = this.getCell().getGridSquare((int)this.x, (int)this.y, int0);
                if (this.current != null) {
                    break;
                }
            }
        }

        if (this.movingSq != null) {
            this.movingSq.getMovingObjects().remove(this);
            this.movingSq = null;
        }

        if (this.current != null && !this.current.getMovingObjects().contains(this)) {
            this.current.getMovingObjects().add(this);
            this.movingSq = this.current;
        }

        this.square = this.current;
        if (this.sprite.hasActiveModel()) {
            this.updateAnimationPlayer(this.getAnimationPlayer(), null);

            for (int int1 = 0; int1 < this.models.size(); int1++) {
                BaseVehicle.ModelInfo modelInfo = (BaseVehicle.ModelInfo)this.models.get(int1);
                this.updateAnimationPlayer(modelInfo.getAnimationPlayer(), modelInfo.part);
            }
        }
    }

    protected void updateAnimationPlayer(AnimationPlayer animationPlayer, VehiclePart vehiclePart) {
        if (animationPlayer != null && animationPlayer.isReady()) {
            AnimationMultiTrack animationMultiTrack = animationPlayer.getMultiTrack();
            float _float = 0.016666668F;
            _float *= 0.8F;
            _float *= zombie.GameTime.instance.getUnmoddedMultiplier();
            animationPlayer.Update(_float);

            for (int _int = 0; _int < animationMultiTrack.getTrackCount(); _int++) {
                AnimationTrack animationTrack0 = (AnimationTrack)animationMultiTrack.getTracks().get(_int);
                if (animationTrack0.IsPlaying && animationTrack0.isFinished()) {
                    animationMultiTrack.removeTrackAt(_int);
                    _int--;
                }
            }

            if (vehiclePart != null) {
                BaseVehicle.ModelInfo modelInfo = this.getModelInfoForPart(vehiclePart);
                if (modelInfo.m_track != null && animationMultiTrack.getIndexOfTrack(modelInfo.m_track) == -1) {
                    modelInfo.m_track = null;
                }

                if (modelInfo.m_track != null) {
                    VehicleWindow vehicleWindow0 = vehiclePart.getWindow();
                    if (vehicleWindow0 != null) {
                        AnimationTrack animationTrack1 = modelInfo.m_track;
                        animationTrack1.setCurrentTimeValue(animationTrack1.getDuration() * vehicleWindow0.getOpenDelta());
                    }
                } else {
                    VehicleDoor vehicleDoor = vehiclePart.getDoor();
                    if (vehicleDoor != null) {
                        this.playPartAnim(vehiclePart, vehicleDoor.isOpen() ? "Opened" : "Closed");
                    }

                    VehicleWindow vehicleWindow1 = vehiclePart.getWindow();
                    if (vehicleWindow1 != null) {
                        this.playPartAnim(vehiclePart, "ClosedToOpen");
                    }
                }
            }
        }
    }

    @Override
    public void saveChange(String string, KahluaTable kahluaTable, ByteBuffer byteBuffer) {
        super.saveChange(string, kahluaTable, byteBuffer);
    }

    @Override
    public void loadChange(String change, ByteBuffer bb) {
        super.loadChange(change, bb);
    }

    public void authorizationClientCollide(IsoPlayer driver) {
        if (driver != null && this.getDriver() == null) {
            this.setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, driver.getOnlineID());
            this.authSimulationTime = System.currentTimeMillis();
            this.interpolation.clear();
            if (this.getVehicleTowing() != null) {
                this.getVehicleTowing().setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, driver.getOnlineID());
                this.getVehicleTowing().authSimulationTime = System.currentTimeMillis();
                this.getVehicleTowing().interpolation.clear();
            } else if (this.getVehicleTowedBy() != null) {
                this.getVehicleTowedBy().setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, driver.getOnlineID());
                this.getVehicleTowedBy().authSimulationTime = System.currentTimeMillis();
                this.getVehicleTowedBy().interpolation.clear();
            }
        }
    }

    public void authorizationServerCollide(short PlayerID, boolean isCollide) {
        if (!this.isNetPlayerAuthorization(BaseVehicle.Authorization.Local)) {
            if (isCollide) {
                this.setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, PlayerID);
                if (this.getVehicleTowing() != null) {
                    this.getVehicleTowing().setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, PlayerID);
                } else if (this.getVehicleTowedBy() != null) {
                    this.getVehicleTowedBy().setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, PlayerID);
                }
            } else {
                BaseVehicle.Authorization authorization = PlayerID == -1 ? BaseVehicle.Authorization.Server : BaseVehicle.Authorization.Local;
                this.setNetPlayerAuthorization(authorization, PlayerID);
                if (this.getVehicleTowing() != null) {
                    this.getVehicleTowing().setNetPlayerAuthorization(authorization, PlayerID);
                } else if (this.getVehicleTowedBy() != null) {
                    this.getVehicleTowedBy().setNetPlayerAuthorization(authorization, PlayerID);
                }
            }
        }
    }

    public void authorizationServerOnSeat(IsoPlayer player, boolean enter) {
        BaseVehicle baseVehicle0 = this.getVehicleTowing();
        BaseVehicle baseVehicle1 = this.getVehicleTowedBy();
        if (this.isNetPlayerId((short)-1) && enter) {
            if (baseVehicle0 != null && baseVehicle0.getDriver() == null) {
                this.addPointConstraint(null, baseVehicle0, this.getTowAttachmentSelf(), baseVehicle0.getTowAttachmentSelf());
            } else if (baseVehicle1 != null && baseVehicle1.getDriver() == null) {
                this.addPointConstraint(null, baseVehicle1, this.getTowAttachmentSelf(), baseVehicle1.getTowAttachmentSelf());
            } else {
                this.setNetPlayerAuthorization(BaseVehicle.Authorization.Local, player.getOnlineID());
            }
        } else if (this.isNetPlayerId(player.getOnlineID()) && !enter) {
            if (baseVehicle0 != null && baseVehicle0.getDriver() != null) {
                baseVehicle0.addPointConstraint(null, this, baseVehicle0.getTowAttachmentSelf(), this.getTowAttachmentSelf());
            } else if (baseVehicle1 != null && baseVehicle1.getDriver() != null) {
                baseVehicle1.addPointConstraint(null, this, baseVehicle1.getTowAttachmentSelf(), this.getTowAttachmentSelf());
            } else {
                this.setNetPlayerAuthorization(BaseVehicle.Authorization.Server, -1);
                if (baseVehicle0 != null) {
                    baseVehicle0.setNetPlayerAuthorization(BaseVehicle.Authorization.Server, -1);
                } else if (baseVehicle1 != null) {
                    baseVehicle1.setNetPlayerAuthorization(BaseVehicle.Authorization.Server, -1);
                }
            }
        }
    }

    public boolean hasAuthorization(UdpConnection connection) {
        if (!this.isNetPlayerId((short)-1) && connection != null) {
            if (GameServer.bServer) {
                for (int _int = 0; _int < connection.players.length; _int++) {
                    if (connection.players[_int] != null && this.isNetPlayerId(connection.players[_int].OnlineID)) {
                        return true;
                    }
                }

                return false;
            } else {
                return this.isNetPlayerId(IsoPlayer.getInstance().getOnlineID());
            }
        } else {
            return false;
        }
    }

    public void netPlayerServerSendAuthorisation(ByteBuffer bb) {
        bb.put(this.netPlayerAuthorization.index());
        bb.putShort(this.netPlayerId);
    }

    public void netPlayerFromServerUpdate(BaseVehicle.Authorization authorization, short authorizationPlayer) {
        if (!this.isNetPlayerAuthorization(authorization) || !this.isNetPlayerId(authorizationPlayer)) {
            if (BaseVehicle.Authorization.Local.equals(authorization)) {
                if (IsoPlayer.getLocalPlayerByOnlineID(authorizationPlayer) != null) {
                    this.setNetPlayerAuthorization(BaseVehicle.Authorization.Local, authorizationPlayer);
                } else {
                    this.setNetPlayerAuthorization(BaseVehicle.Authorization.Remote, authorizationPlayer);
                }
            } else if (BaseVehicle.Authorization.LocalCollide.equals(authorization)) {
                if (IsoPlayer.getLocalPlayerByOnlineID(authorizationPlayer) != null) {
                    this.setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, authorizationPlayer);
                } else {
                    this.setNetPlayerAuthorization(BaseVehicle.Authorization.RemoteCollide, authorizationPlayer);
                }
            } else {
                this.setNetPlayerAuthorization(BaseVehicle.Authorization.Server, -1);
            }
        }
    }

    public Transform getWorldTransform(Transform out) {
        out.set(this.jniTransform);
        return out;
    }

    public void setWorldTransform(Transform in) {
        this.jniTransform.set(in);
        Quaternionf quaternionf = this.tempQuat4f;
        in.getRotation(quaternionf);
        if (!GameServer.bServer) {
            Bullet.teleportVehicle(
                this.VehicleID,
                in.origin.x + WorldSimulation.instance.offsetX,
                in.origin.z + WorldSimulation.instance.offsetY,
                in.origin.y,
                quaternionf.x,
                quaternionf.y,
                quaternionf.z,
                quaternionf.w
            );
        }
    }

    public void flipUpright() {
        Transform transform = this.tempTransform;
        transform.set(this.jniTransform);
        Quaternionf quaternionf = this.tempQuat4f;
        quaternionf.setAngleAxis(0.0F, _UNIT_Y.x, _UNIT_Y.y, _UNIT_Y.z);
        transform.setRotation(quaternionf);
        this.setWorldTransform(transform);
    }

    public void setAngles(float degreesX, float degreesY, float degreesZ) {
        if ((int)degreesX != (int)this.getAngleX() || (int)degreesY != (int)this.getAngleY() || degreesZ != (float)((int)this.getAngleZ())) {
            this.polyDirty = true;
            float float0 = degreesX * (float) (Math.PI / 180.0);
            float float1 = degreesY * (float) (Math.PI / 180.0);
            float float2 = degreesZ * (float) (Math.PI / 180.0);
            this.tempQuat4f.rotationXYZ(float0, float1, float2);
            this.tempTransform.set(this.jniTransform);
            this.tempTransform.setRotation(this.tempQuat4f);
            this.setWorldTransform(this.tempTransform);
        }
    }

    public float getAngleX() {
        Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        this.jniTransform.getRotation(this.tempQuat4f).getEulerAnglesXYZ(vector3f);
        float _float = vector3f.x * (180.0F / (float)Math.PI);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return _float;
    }

    public float getAngleY() {
        Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        this.jniTransform.getRotation(this.tempQuat4f).getEulerAnglesXYZ(vector3f);
        float _float = vector3f.y * (180.0F / (float)Math.PI);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return _float;
    }

    public float getAngleZ() {
        Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        this.jniTransform.getRotation(this.tempQuat4f).getEulerAnglesXYZ(vector3f);
        float _float = vector3f.z * (180.0F / (float)Math.PI);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return _float;
    }

    public void setDebugZ(float z) {
        this.tempTransform.set(this.jniTransform);
        this.tempTransform.origin.y = PZMath.clamp(z, 0.0F, 1.0F) * 3.0F * 0.82F;
        this.setWorldTransform(this.tempTransform);
    }

    public void setPhysicsActive(boolean active) {
        if (this.physics != null && active != this.physics.isEnable) {
            this.physics.isEnable = active;
            if (!GameServer.bServer) {
                Bullet.setVehicleActive(this.VehicleID, active);
            }

            if (active) {
                this.physicActiveCheck = System.currentTimeMillis() + 3000L;
            }
        }
    }

    public float getDebugZ() {
        return this.jniTransform.origin.y / 2.46F;
    }

    public PolygonalMap2.VehiclePoly getPoly() {
        if (this.polyDirty) {
            if (this.polyGarageCheck && this.square != null) {
                if (this.square.getRoom() != null && this.square.getRoom().RoomDef != null && this.square.getRoom().RoomDef.contains("garagestorage")) {
                    this.radiusReductionInGarage = -0.3F;
                } else {
                    this.radiusReductionInGarage = 0.0F;
                }

                this.polyGarageCheck = false;
            }

            this.poly.init(this, 0.0F);
            this.polyPlusRadius.init(this, PLUS_RADIUS + this.radiusReductionInGarage);
            this.polyDirty = false;
            this.polyPlusRadiusMinX = -123.0F;
            this.initShadowPoly();
        }

        return this.poly;
    }

    public PolygonalMap2.VehiclePoly getPolyPlusRadius() {
        if (this.polyDirty) {
            if (this.polyGarageCheck && this.square != null) {
                if (this.square.getRoom() != null && this.square.getRoom().RoomDef != null && this.square.getRoom().RoomDef.contains("garagestorage")) {
                    this.radiusReductionInGarage = -0.3F;
                } else {
                    this.radiusReductionInGarage = 0.0F;
                }

                this.polyGarageCheck = false;
            }

            this.poly.init(this, 0.0F);
            this.polyPlusRadius.init(this, PLUS_RADIUS + this.radiusReductionInGarage);
            this.polyDirty = false;
            this.polyPlusRadiusMinX = -123.0F;
            this.initShadowPoly();
        }

        return this.polyPlusRadius;
    }

    private void initShadowPoly() {
        this.getWorldTransform(this.tempTransform);
        Quaternionf quaternionf = this.tempTransform.getRotation(this.tempQuat4f);
        Vector2f vector2f0 = this.script.getShadowExtents();
        Vector2f vector2f1 = this.script.getShadowOffset();
        float float0 = vector2f0.x / 2.0F;
        float float1 = vector2f0.y / 2.0F;
        Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        if (quaternionf.x < 0.0F) {
            this.getWorldPos(vector2f1.x - float0, 0.0F, vector2f1.y + float1, vector3f);
            this.shadowCoord.x1 = vector3f.x;
            this.shadowCoord.y1 = vector3f.y;
            this.getWorldPos(vector2f1.x + float0, 0.0F, vector2f1.y + float1, vector3f);
            this.shadowCoord.x2 = vector3f.x;
            this.shadowCoord.y2 = vector3f.y;
            this.getWorldPos(vector2f1.x + float0, 0.0F, vector2f1.y - float1, vector3f);
            this.shadowCoord.x3 = vector3f.x;
            this.shadowCoord.y3 = vector3f.y;
            this.getWorldPos(vector2f1.x - float0, 0.0F, vector2f1.y - float1, vector3f);
            this.shadowCoord.x4 = vector3f.x;
            this.shadowCoord.y4 = vector3f.y;
        } else {
            this.getWorldPos(vector2f1.x - float0, 0.0F, vector2f1.y + float1, vector3f);
            this.shadowCoord.x1 = vector3f.x;
            this.shadowCoord.y1 = vector3f.y;
            this.getWorldPos(vector2f1.x + float0, 0.0F, vector2f1.y + float1, vector3f);
            this.shadowCoord.x2 = vector3f.x;
            this.shadowCoord.y2 = vector3f.y;
            this.getWorldPos(vector2f1.x + float0, 0.0F, vector2f1.y - float1, vector3f);
            this.shadowCoord.x3 = vector3f.x;
            this.shadowCoord.y3 = vector3f.y;
            this.getWorldPos(vector2f1.x - float0, 0.0F, vector2f1.y - float1, vector3f);
            this.shadowCoord.x4 = vector3f.x;
            this.shadowCoord.y4 = vector3f.y;
        }

        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
    }

    private void initPolyPlusRadiusBounds() {
        if (this.polyPlusRadiusMinX == -123.0F) {
            PolygonalMap2.VehiclePoly vehiclePoly = this.getPolyPlusRadius();
            Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            Vector3f vector3f1 = this.getLocalPos(vehiclePoly.x1, vehiclePoly.y1, vehiclePoly.z, vector3f0);
            float float0 = (float)((int)(vector3f1.x * 100.0F)) / 100.0F;
            float float1 = (float)((int)(vector3f1.z * 100.0F)) / 100.0F;
            vector3f1 = this.getLocalPos(vehiclePoly.x2, vehiclePoly.y2, vehiclePoly.z, vector3f0);
            float float2 = (float)((int)(vector3f1.x * 100.0F)) / 100.0F;
            float float3 = (float)((int)(vector3f1.z * 100.0F)) / 100.0F;
            vector3f1 = this.getLocalPos(vehiclePoly.x3, vehiclePoly.y3, vehiclePoly.z, vector3f0);
            float float4 = (float)((int)(vector3f1.x * 100.0F)) / 100.0F;
            float float5 = (float)((int)(vector3f1.z * 100.0F)) / 100.0F;
            vector3f1 = this.getLocalPos(vehiclePoly.x4, vehiclePoly.y4, vehiclePoly.z, vector3f0);
            float float6 = (float)((int)(vector3f1.x * 100.0F)) / 100.0F;
            float float7 = (float)((int)(vector3f1.z * 100.0F)) / 100.0F;
            this.polyPlusRadiusMinX = Math.min(float0, Math.min(float2, Math.min(float4, float6)));
            this.polyPlusRadiusMaxX = Math.max(float0, Math.max(float2, Math.max(float4, float6)));
            this.polyPlusRadiusMinY = Math.min(float1, Math.min(float3, Math.min(float5, float7)));
            this.polyPlusRadiusMaxY = Math.max(float1, Math.max(float3, Math.max(float5, float7)));
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
        }
    }

    public Vector3f getForwardVector(Vector3f vector3f) {
        byte _byte = 2;
        return this.jniTransform.basis.getColumn(_byte, vector3f);
    }

    public Vector3f getUpVector(Vector3f vector3f) {
        byte _byte = 1;
        return this.jniTransform.basis.getColumn(_byte, vector3f);
    }

    public float getUpVectorDot() {
        Vector3f vector3f = this.getUpVector(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        float _float = vector3f.dot(_UNIT_Y);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return _float;
    }

    public boolean isStopped() {
        return this.jniSpeed > -0.8F && this.jniSpeed < 0.8F && !this.getController().isGasPedalPressed();
    }

    public float getCurrentSpeedKmHour() {
        return this.jniSpeed;
    }

    public Vector3f getLinearVelocity(Vector3f vector3f) {
        return vector3f.set(this.jniLinearVelocity);
    }

    public float getSpeed2D() {
        float float0 = this.jniLinearVelocity.x;
        float float1 = this.jniLinearVelocity.z;
        return (float)Math.sqrt((double)(float0 * float0 + float1 * float1));
    }

    public boolean isAtRest() {
        if (this.physics == null) {
            return true;
        } else {
            float _float = this.jniLinearVelocity.y;
            return Math.abs(this.physics.EngineForce) < 0.01F && this.getSpeed2D() < 0.02F && Math.abs(_float) < 0.5F;
        }
    }

    protected void updateTransform() {
        if (this.sprite.modelSlot != null) {
            float float0 = this.getScript().getModelScale();
            float float1 = 1.0F;
            if (this.sprite.modelSlot != null && this.sprite.modelSlot.model.scale != 1.0F) {
                float1 = this.sprite.modelSlot.model.scale;
            }

            Transform transform = this.getWorldTransform(this.tempTransform);
            Quaternionf quaternionf0 = ((BaseVehicle.QuaternionfObjectPool)TL_quaternionf_pool.get()).alloc();
            Quaternionf quaternionf1 = ((BaseVehicle.QuaternionfObjectPool)TL_quaternionf_pool.get()).alloc();
            Matrix4f matrix4f0 = ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).alloc();
            transform.getRotation(quaternionf0);
            quaternionf0.y *= -1.0F;
            quaternionf0.z *= -1.0F;
            Matrix4f matrix4f1 = quaternionf0.get(matrix4f0);
            float float2 = 1.0F;
            if (this.sprite.modelSlot.model.m_modelScript != null) {
                float2 = this.sprite.modelSlot.model.m_modelScript.invertX ? -1.0F : 1.0F;
            }

            Vector3f vector3f0 = this.script.getModel().getOffset();
            Vector3f vector3f1 = this.getScript().getModel().getRotate();
            quaternionf1.rotationXYZ(vector3f1.x * (float) (Math.PI / 180.0), vector3f1.y * (float) (Math.PI / 180.0), vector3f1.z * (float) (Math.PI / 180.0));
            this.renderTransform
                .translationRotateScale(
                    vector3f0.x * -1.0F,
                    vector3f0.y,
                    vector3f0.z,
                    quaternionf1.x,
                    quaternionf1.y,
                    quaternionf1.z,
                    quaternionf1.w,
                    float0 * float1 * float2,
                    float0 * float1,
                    float0 * float1
                );
            matrix4f1.mul(this.renderTransform, this.renderTransform);
            this.vehicleTransform.translationRotateScale(vector3f0.x * -1.0F, vector3f0.y, vector3f0.z, 0.0F, 0.0F, 0.0F, 1.0F, float0);
            matrix4f1.mul(this.vehicleTransform, this.vehicleTransform);

            for (int _int = 0; _int < this.models.size(); _int++) {
                BaseVehicle.ModelInfo modelInfo = (BaseVehicle.ModelInfo)this.models.get(_int);
                VehicleScript.Model model = modelInfo.scriptModel;
                vector3f1 = model.getOffset();
                Vector3f vector3f2 = model.getRotate();
                float float3 = model.scale;
                float1 = 1.0F;
                float float4 = 1.0F;
                if (modelInfo.modelScript != null) {
                    float1 = modelInfo.modelScript.scale;
                    float4 = modelInfo.modelScript.invertX ? -1.0F : 1.0F;
                }

                quaternionf1.rotationXYZ(
                    vector3f2.x * (float) (Math.PI / 180.0), vector3f2.y * (float) (Math.PI / 180.0), vector3f2.z * (float) (Math.PI / 180.0)
                );
                if (modelInfo.wheelIndex == -1) {
                    modelInfo.renderTransform
                        .translationRotateScale(
                            vector3f1.x * -1.0F,
                            vector3f1.y,
                            vector3f1.z,
                            quaternionf1.x,
                            quaternionf1.y,
                            quaternionf1.z,
                            quaternionf1.w,
                            float3 * float1 * float4,
                            float3 * float1,
                            float3 * float1
                        );
                    this.vehicleTransform.mul(modelInfo.renderTransform, modelInfo.renderTransform);
                } else {
                    BaseVehicle.WheelInfo wheelInfox = this.wheelInfo[modelInfo.wheelIndex];
                    float float5 = wheelInfox.steering;
                    float float6 = wheelInfox.rotation;
                    VehicleScript.Wheel wheel = this.getScript().getWheel(modelInfo.wheelIndex);
                    BaseVehicle.VehicleImpulse vehicleImpulse = modelInfo.wheelIndex < this.impulseFromSquishedZombie.length
                        ? this.impulseFromSquishedZombie[modelInfo.wheelIndex]
                        : null;
                    float float7 = vehicleImpulse != null && vehicleImpulse.enable ? 0.05F : 0.0F;
                    if (wheelInfox.suspensionLength == 0.0F) {
                        matrix4f0.translation(wheel.offset.x / float0 * -1.0F, wheel.offset.y / float0, wheel.offset.z / float0);
                    } else {
                        matrix4f0.translation(
                            wheel.offset.x / float0 * -1.0F,
                            (wheel.offset.y + this.script.getSuspensionRestLength() - wheelInfox.suspensionLength) / float0 + float7 * 0.5F,
                            wheel.offset.z / float0
                        );
                    }

                    modelInfo.renderTransform.identity();
                    modelInfo.renderTransform.mul(matrix4f0);
                    modelInfo.renderTransform.rotateY(float5 * -1.0F);
                    modelInfo.renderTransform.rotateX(float6);
                    matrix4f0.translationRotateScale(
                        vector3f1.x * -1.0F,
                        vector3f1.y,
                        vector3f1.z,
                        quaternionf1.x,
                        quaternionf1.y,
                        quaternionf1.z,
                        quaternionf1.w,
                        float3 * float1 * float4,
                        float3 * float1,
                        float3 * float1
                    );
                    modelInfo.renderTransform.mul(matrix4f0);
                    this.vehicleTransform.mul(modelInfo.renderTransform, modelInfo.renderTransform);
                }
            }

            ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).release(matrix4f0);
            ((BaseVehicle.QuaternionfObjectPool)TL_quaternionf_pool.get()).release(quaternionf0);
            ((BaseVehicle.QuaternionfObjectPool)TL_quaternionf_pool.get()).release(quaternionf1);
        }
    }

    public void updatePhysics() {
        this.physics.update();
    }

    public void updatePhysicsNetwork() {
        if (this.limitPhysicSend.Check()) {
            VehicleManager.instance.sendPhysic(this);
            if (this.limitPhysicPositionSent == null) {
                this.limitPhysicPositionSent = new Vector2();
            } else if (IsoUtils.DistanceToSquared(this.limitPhysicPositionSent.x, this.limitPhysicPositionSent.y, this.x, this.y) > 0.001F) {
                this.limitPhysicSend.setUpdatePeriod(150L);
            } else {
                this.limitPhysicSend.setSmoothUpdatePeriod(300L);
            }

            this.limitPhysicPositionSent.set(this.x, this.y);
        }
    }

    public void checkPhysicsValidWithServer() {
        float float0 = 0.05F;
        if (this.limitPhysicValid.Check() && Bullet.getOwnVehiclePhysics(this.VehicleID, physicsParams) == 0) {
            float float1 = Math.abs(physicsParams[0] - this.x);
            float float2 = Math.abs(physicsParams[1] - this.y);
            if (float1 > float0 || float2 > float0) {
                VehicleManager.instance.sendRequestGetPosition(this.VehicleID, PacketTypes.PacketType.Vehicles);
                DebugLog.Vehicle.trace("diff-x=%f diff-y=%f delta=%f", float1, float2, float0);
            }
        }
    }

    public void updateControls() {
        if (this.getController() != null) {
            if (this.isOperational()) {
                IsoPlayer isoPlayer = Type.tryCastTo(this.getDriver(), IsoPlayer.class);
                if (isoPlayer == null || !isoPlayer.isBlockMovement()) {
                    this.getController().updateControls();
                }
            }
        }
    }

    public boolean isKeyboardControlled() {
        IsoGameCharacter isoGameCharacter = this.getCharacter(0);
        return isoGameCharacter != null && isoGameCharacter == IsoPlayer.players[0] && this.getVehicleTowedBy() == null;
    }

    public int getJoypad() {
        IsoGameCharacter isoGameCharacter = this.getCharacter(0);
        return isoGameCharacter != null && isoGameCharacter instanceof IsoPlayer ? ((IsoPlayer)isoGameCharacter).JoypadBind : -1;
    }

    @Override
    public void Damage(float amount) {
        this.crash(amount, true);
    }

    @Override
    public void HitByVehicle(BaseVehicle vehicle, float amount) {
        this.crash(amount, true);
    }

    public void crash(float delta, boolean front) {
        if (GameClient.bClient) {
            zombie.SoundManager.instance.PlayWorldSound(this.getCrashSound(delta), this.square, 1.0F, 20.0F, 1.0F, true);
            GameClient.instance.sendClientCommandV(null, "vehicle", "crash", "vehicle", this.getId(), "amount", delta, "front", front);
        } else {
            float _float = 1.3F;
            switch (zombie.SandboxOptions.instance.CarDamageOnImpact.getValue()) {
                case 1:
                    _float = 1.9F;
                    break;
                case 2:
                    _float = 1.6F;
                case 3:
                default:
                    break;
                case 4:
                    _float = 1.1F;
                    break;
                case 5:
                    _float = 0.9F;
            }

            delta = Math.abs(delta) / _float;
            if (front) {
                this.addDamageFront((int)delta);
            } else {
                this.addDamageRear((int)Math.abs(delta / _float));
            }

            this.damagePlayers(Math.abs(delta));
            zombie.SoundManager.instance.PlayWorldSound(this.getCrashSound(delta), this.square, 1.0F, 20.0F, 1.0F, true);
        }
    }

    private String getCrashSound(float _float) {
        if (_float < 5.0F) {
            return "VehicleCrash1";
        } else {
            return _float < 30.0F ? "VehicleCrash2" : "VehicleCrash";
        }
    }

    public void addDamageFrontHitAChr(int dmg) {
        if (dmg >= 4 || !Rand.NextBool(7)) {
            VehiclePart vehiclePart = this.getPartById("EngineDoor");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, dmg - 10), dmg + 3));
            }

            if (vehiclePart != null && (vehiclePart.getCondition() <= 0 || vehiclePart.getInventoryItem() == null) && Rand.NextBool(4)) {
                vehiclePart = this.getPartById("Engine");
                if (vehiclePart != null) {
                    vehiclePart.damage(Rand.Next(2, 4));
                }
            }

            if (dmg > 12) {
                vehiclePart = this.getPartById("Windshield");
                if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                    vehiclePart.damage(Rand.Next(Math.max(1, dmg - 10), dmg + 3));
                }
            }

            if (Rand.Next(5) < dmg) {
                if (Rand.NextBool(2)) {
                    vehiclePart = this.getPartById("TireFrontLeft");
                } else {
                    vehiclePart = this.getPartById("TireFrontRight");
                }

                if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                    vehiclePart.damage(Rand.Next(1, 3));
                }
            }

            if (Rand.Next(7) < dmg) {
                this.damageHeadlight("HeadlightLeft", Rand.Next(1, 4));
            }

            if (Rand.Next(7) < dmg) {
                this.damageHeadlight("HeadlightRight", Rand.Next(1, 4));
            }

            float _float = this.getBloodIntensity("Front");
            this.setBloodIntensity("Front", _float + 0.01F);
        }
    }

    public void addDamageRearHitAChr(int dmg) {
        if (dmg >= 4 || !Rand.NextBool(7)) {
            VehiclePart vehiclePart = this.getPartById("TruckBed");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.setCondition(vehiclePart.getCondition() - Rand.Next(Math.max(1, dmg - 10), dmg + 3));
                vehiclePart.doInventoryItemStats(vehiclePart.getInventoryItem(), 0);
                this.transmitPartCondition(vehiclePart);
            }

            vehiclePart = this.getPartById("DoorRear");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, dmg - 10), dmg + 3));
            }

            vehiclePart = this.getPartById("TrunkDoor");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, dmg - 10), dmg + 3));
            }

            if (dmg > 12) {
                vehiclePart = this.getPartById("WindshieldRear");
                if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                    vehiclePart.damage(dmg);
                }
            }

            if (Rand.Next(5) < dmg) {
                if (Rand.NextBool(2)) {
                    vehiclePart = this.getPartById("TireRearLeft");
                } else {
                    vehiclePart = this.getPartById("TireRearRight");
                }

                if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                    vehiclePart.damage(Rand.Next(1, 3));
                }
            }

            if (Rand.Next(7) < dmg) {
                this.damageHeadlight("HeadlightRearLeft", Rand.Next(1, 4));
            }

            if (Rand.Next(7) < dmg) {
                this.damageHeadlight("HeadlightRearRight", Rand.Next(1, 4));
            }

            if (Rand.Next(6) < dmg) {
                vehiclePart = this.getPartById("GasTank");
                if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                    vehiclePart.damage(Rand.Next(1, 3));
                }
            }

            float _float = this.getBloodIntensity("Rear");
            this.setBloodIntensity("Rear", _float + 0.01F);
        }
    }

    private void addDamageFront(int _int) {
        this.currentFrontEndDurability -= _int;
        VehiclePart vehiclePart = this.getPartById("EngineDoor");
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
        }

        if (vehiclePart == null || vehiclePart.getInventoryItem() == null || vehiclePart.getCondition() < 25) {
            vehiclePart = this.getPartById("Engine");
            if (vehiclePart != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 3), _int + 3));
            }
        }

        vehiclePart = this.getPartById("Windshield");
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
        }

        if (Rand.Next(4) == 0) {
            vehiclePart = this.getPartById("DoorFrontLeft");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }

            vehiclePart = this.getPartById("WindowFrontLeft");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }
        }

        if (Rand.Next(4) == 0) {
            vehiclePart = this.getPartById("DoorFrontRight");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }

            vehiclePart = this.getPartById("WindowFrontRight");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }
        }

        if (Rand.Next(20) < _int) {
            this.damageHeadlight("HeadlightLeft", _int);
        }

        if (Rand.Next(20) < _int) {
            this.damageHeadlight("HeadlightRight", _int);
        }
    }

    private void addDamageRear(int _int) {
        this.currentRearEndDurability -= _int;
        VehiclePart vehiclePart = this.getPartById("TruckBed");
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.setCondition(vehiclePart.getCondition() - Rand.Next(Math.max(1, _int - 5), _int + 5));
            vehiclePart.doInventoryItemStats(vehiclePart.getInventoryItem(), 0);
            this.transmitPartCondition(vehiclePart);
        }

        vehiclePart = this.getPartById("DoorRear");
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
        }

        vehiclePart = this.getPartById("TrunkDoor");
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
        }

        vehiclePart = this.getPartById("WindshieldRear");
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.damage(_int);
        }

        if (Rand.Next(4) == 0) {
            vehiclePart = this.getPartById("DoorRearLeft");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }

            vehiclePart = this.getPartById("WindowRearLeft");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }
        }

        if (Rand.Next(4) == 0) {
            vehiclePart = this.getPartById("DoorRearRight");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }

            vehiclePart = this.getPartById("WindowRearRight");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }
        }

        if (Rand.Next(20) < _int) {
            this.damageHeadlight("HeadlightRearLeft", _int);
        }

        if (Rand.Next(20) < _int) {
            this.damageHeadlight("HeadlightRearRight", _int);
        }

        if (Rand.Next(20) < _int) {
            vehiclePart = this.getPartById("Muffler");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                vehiclePart.damage(Rand.Next(Math.max(1, _int - 5), _int + 5));
            }
        }
    }

    private void damageHeadlight(String string, int _int) {
        VehiclePart vehiclePart = this.getPartById(string);
        if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.damage(_int);
            if (vehiclePart.getCondition() <= 0) {
                vehiclePart.setInventoryItem(null);
                this.transmitPartItem(vehiclePart);
            }
        }
    }

    private float clamp(float float0, float float1, float float2) {
        if (float0 < float1) {
            float0 = float1;
        }

        if (float0 > float2) {
            float0 = float2;
        }

        return float0;
    }

    public boolean isCharacterAdjacentTo(IsoGameCharacter chr) {
        if ((int)chr.z != (int)this.z) {
            return false;
        } else {
            Transform transform = this.getWorldTransform(this.tempTransform);
            transform.inverse();
            Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            vector3f0.set(chr.x - WorldSimulation.instance.offsetX, 0.0F, chr.y - WorldSimulation.instance.offsetY);
            transform.transform(vector3f0);
            Vector3f vector3f1 = this.script.getExtents();
            Vector3f vector3f2 = this.script.getCenterOfMassOffset();
            float float0 = vector3f2.x - vector3f1.x / 2.0F;
            float float1 = vector3f2.x + vector3f1.x / 2.0F;
            float float2 = vector3f2.z - vector3f1.z / 2.0F;
            float float3 = vector3f2.z + vector3f1.z / 2.0F;
            if (vector3f0.x >= float0 - 0.5F && vector3f0.x < float1 + 0.5F && vector3f0.z >= float2 - 0.5F && vector3f0.z < float3 + 0.5F) {
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                return true;
            } else {
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                return false;
            }
        }
    }

    public Vector2 testCollisionWithCharacter(IsoGameCharacter chr, float circleRadius, Vector2 out) {
        if (this.physics == null) {
            return null;
        } else {
            Vector3f vector3f0 = this.script.getExtents();
            Vector3f vector3f1 = this.script.getCenterOfMassOffset();
            if (this.DistToProper(chr) > Math.max(vector3f0.x / 2.0F, vector3f0.z / 2.0F) + circleRadius + 1.0F) {
                return null;
            } else {
                Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                this.getLocalPos(chr.nx, chr.ny, 0.0F, vector3f2);
                float float0 = vector3f1.x - vector3f0.x / 2.0F;
                float float1 = vector3f1.x + vector3f0.x / 2.0F;
                float float2 = vector3f1.z - vector3f0.z / 2.0F;
                float float3 = vector3f1.z + vector3f0.z / 2.0F;
                if (vector3f2.x > float0 && vector3f2.x < float1 && vector3f2.z > float2 && vector3f2.z < float3) {
                    float float4 = vector3f2.x - float0;
                    float float5 = float1 - vector3f2.x;
                    float float6 = vector3f2.z - float2;
                    float float7 = float3 - vector3f2.z;
                    Vector3f vector3f3 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                    if (float4 < float5 && float4 < float6 && float4 < float7) {
                        vector3f3.set(float0 - circleRadius - 0.015F, 0.0F, vector3f2.z);
                    } else if (float5 < float4 && float5 < float6 && float5 < float7) {
                        vector3f3.set(float1 + circleRadius + 0.015F, 0.0F, vector3f2.z);
                    } else if (float6 < float4 && float6 < float5 && float6 < float7) {
                        vector3f3.set(vector3f2.x, 0.0F, float2 - circleRadius - 0.015F);
                    } else if (float7 < float4 && float7 < float5 && float7 < float6) {
                        vector3f3.set(vector3f2.x, 0.0F, float3 + circleRadius + 0.015F);
                    }

                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                    Transform transform0 = this.getWorldTransform(this.tempTransform);
                    transform0.origin.set(0.0F, 0.0F, 0.0F);
                    transform0.transform(vector3f3);
                    vector3f3.x = vector3f3.x + this.getX();
                    vector3f3.z = vector3f3.z + this.getY();
                    this.collideX = vector3f3.x;
                    this.collideY = vector3f3.z;
                    out.set(vector3f3.x, vector3f3.z);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f3);
                    return out;
                } else {
                    float float8 = this.clamp(vector3f2.x, float0, float1);
                    float float9 = this.clamp(vector3f2.z, float2, float3);
                    float float10 = vector3f2.x - float8;
                    float float11 = vector3f2.z - float9;
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                    float float12 = float10 * float10 + float11 * float11;
                    if (float12 < circleRadius * circleRadius) {
                        if (float10 == 0.0F && float11 == 0.0F) {
                            return out.set(-1.0F, -1.0F);
                        } else {
                            Vector3f vector3f4 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                            vector3f4.set(float10, 0.0F, float11);
                            vector3f4.normalize();
                            vector3f4.mul(circleRadius + 0.015F);
                            vector3f4.x += float8;
                            vector3f4.z += float9;
                            Transform transform1 = this.getWorldTransform(this.tempTransform);
                            transform1.origin.set(0.0F, 0.0F, 0.0F);
                            transform1.transform(vector3f4);
                            vector3f4.x = vector3f4.x + this.getX();
                            vector3f4.z = vector3f4.z + this.getY();
                            this.collideX = vector3f4.x;
                            this.collideY = vector3f4.z;
                            out.set(vector3f4.x, vector3f4.z);
                            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f4);
                            return out;
                        }
                    } else {
                        return null;
                    }
                }
            }
        }
    }

    public int testCollisionWithProneCharacter(IsoGameCharacter chr, boolean doSound) {
        Vector2 vector2 = chr.getAnimVector(((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc());
        int _int = this.testCollisionWithProneCharacter(chr, vector2.x, vector2.y, doSound);
        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
        return _int;
    }

    public int testCollisionWithCorpse(IsoDeadBody body, boolean doSound) {
        float float0 = (float)Math.cos((double)body.getAngle());
        float float1 = (float)Math.sin((double)body.getAngle());
        return this.testCollisionWithProneCharacter(body, float0, float1, doSound);
    }

    public int testCollisionWithProneCharacter(IsoMovingObject chr, float angleX, float angleY, boolean doSound) {
        if (this.physics == null) {
            return 0;
        } else if (GameServer.bServer) {
            return 0;
        } else {
            Vector3f vector3f0 = this.script.getExtents();
            float float0 = 0.3F;
            if (this.DistToProper(chr) > Math.max(vector3f0.x / 2.0F, vector3f0.z / 2.0F) + float0 + 1.0F) {
                return 0;
            } else if (Math.abs(this.jniSpeed) < 3.0F) {
                return 0;
            } else {
                float float1 = chr.x + angleX * 0.65F;
                float float2 = chr.y + angleY * 0.65F;
                float float3 = chr.x - angleX * 0.65F;
                float float4 = chr.y - angleY * 0.65F;
                int int0 = 0;
                Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();

                for (int int1 = 0; int1 < this.script.getWheelCount(); int1++) {
                    VehicleScript.Wheel wheel = this.script.getWheel(int1);
                    boolean _boolean = true;

                    for (int int2 = 0; int2 < this.models.size(); int2++) {
                        BaseVehicle.ModelInfo modelInfo = (BaseVehicle.ModelInfo)this.models.get(int2);
                        if (modelInfo.wheelIndex == int1) {
                            this.getWorldPos(wheel.offset.x, wheel.offset.y - this.wheelInfo[int1].suspensionLength, wheel.offset.z, vector3f1);
                            if (vector3f1.z > this.script.getWheel(int1).radius + 0.05F) {
                                _boolean = false;
                            }
                            break;
                        }
                    }

                    if (_boolean) {
                        this.getWorldPos(wheel.offset.x, wheel.offset.y, wheel.offset.z, vector3f2);
                        float float5 = vector3f2.x;
                        float float6 = vector3f2.y;
                        double _double = (double)((float5 - float3) * (float1 - float3) + (float6 - float4) * (float2 - float4))
                            / (Math.pow((double)(float1 - float3), 2.0) + Math.pow((double)(float2 - float4), 2.0));
                        float float7;
                        float float8;
                        if (_double <= 0.0) {
                            float7 = float3;
                            float8 = float4;
                        } else if (_double >= 1.0) {
                            float7 = float1;
                            float8 = float2;
                        } else {
                            float7 = float3 + (float1 - float3) * (float)_double;
                            float8 = float4 + (float2 - float4) * (float)_double;
                        }

                        if (!(IsoUtils.DistanceToSquared(vector3f2.x, vector3f2.y, float7, float8) > wheel.radius * wheel.radius)) {
                            if (doSound && Math.abs(this.jniSpeed) > 10.0F) {
                                if (GameServer.bServer && chr instanceof IsoZombie) {
                                    ((IsoZombie)chr).setThumpFlag(1);
                                } else {
                                    zombie.SoundManager.instance.PlayWorldSound("VehicleRunOverBody", chr.getCurrentSquare(), 0.0F, 20.0F, 0.9F, true);
                                }

                                doSound = false;
                            }

                            if (int1 < this.impulseFromSquishedZombie.length) {
                                if (this.impulseFromSquishedZombie[int1] == null) {
                                    this.impulseFromSquishedZombie[int1] = new BaseVehicle.VehicleImpulse();
                                }

                                this.impulseFromSquishedZombie[int1].impulse.set(0.0F, 1.0F, 0.0F);
                                float float9 = Math.max(Math.abs(this.jniSpeed), 20.0F) / 20.0F;
                                this.impulseFromSquishedZombie[int1].impulse.mul(0.065F * this.getFudgedMass() * float9);
                                this.impulseFromSquishedZombie[int1].rel_pos.set(vector3f2.x - this.x, 0.0F, vector3f2.y - this.y);
                                this.impulseFromSquishedZombie[int1].enable = true;
                                int0++;
                            }
                        }
                    }
                }

                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                return int0;
            }
        }
    }

    public Vector2 testCollisionWithObject(IsoObject obj, float circleRadius, Vector2 out) {
        if (this.physics == null) {
            return null;
        } else if (obj.square == null) {
            return null;
        } else {
            float float0 = this.getObjectX(obj);
            float float1 = this.getObjectY(obj);
            Vector3f vector3f0 = this.script.getExtents();
            Vector3f vector3f1 = this.script.getCenterOfMassOffset();
            float float2 = Math.max(vector3f0.x / 2.0F, vector3f0.z / 2.0F) + circleRadius + 1.0F;
            if (this.DistToSquared(float0, float1) > float2 * float2) {
                return null;
            } else {
                Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                this.getLocalPos(float0, float1, 0.0F, vector3f2);
                float float3 = vector3f1.x - vector3f0.x / 2.0F;
                float float4 = vector3f1.x + vector3f0.x / 2.0F;
                float float5 = vector3f1.z - vector3f0.z / 2.0F;
                float float6 = vector3f1.z + vector3f0.z / 2.0F;
                if (vector3f2.x > float3 && vector3f2.x < float4 && vector3f2.z > float5 && vector3f2.z < float6) {
                    float float7 = vector3f2.x - float3;
                    float float8 = float4 - vector3f2.x;
                    float float9 = vector3f2.z - float5;
                    float float10 = float6 - vector3f2.z;
                    Vector3f vector3f3 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                    if (float7 < float8 && float7 < float9 && float7 < float10) {
                        vector3f3.set(float3 - circleRadius - 0.015F, 0.0F, vector3f2.z);
                    } else if (float8 < float7 && float8 < float9 && float8 < float10) {
                        vector3f3.set(float4 + circleRadius + 0.015F, 0.0F, vector3f2.z);
                    } else if (float9 < float7 && float9 < float8 && float9 < float10) {
                        vector3f3.set(vector3f2.x, 0.0F, float5 - circleRadius - 0.015F);
                    } else if (float10 < float7 && float10 < float8 && float10 < float9) {
                        vector3f3.set(vector3f2.x, 0.0F, float6 + circleRadius + 0.015F);
                    }

                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                    Transform transform0 = this.getWorldTransform(this.tempTransform);
                    transform0.origin.set(0.0F, 0.0F, 0.0F);
                    transform0.transform(vector3f3);
                    vector3f3.x = vector3f3.x + this.getX();
                    vector3f3.z = vector3f3.z + this.getY();
                    this.collideX = vector3f3.x;
                    this.collideY = vector3f3.z;
                    out.set(vector3f3.x, vector3f3.z);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f3);
                    return out;
                } else {
                    float float11 = this.clamp(vector3f2.x, float3, float4);
                    float float12 = this.clamp(vector3f2.z, float5, float6);
                    float float13 = vector3f2.x - float11;
                    float float14 = vector3f2.z - float12;
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                    float float15 = float13 * float13 + float14 * float14;
                    if (float15 < circleRadius * circleRadius) {
                        if (float13 == 0.0F && float14 == 0.0F) {
                            return out.set(-1.0F, -1.0F);
                        } else {
                            Vector3f vector3f4 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                            vector3f4.set(float13, 0.0F, float14);
                            vector3f4.normalize();
                            vector3f4.mul(circleRadius + 0.015F);
                            vector3f4.x += float11;
                            vector3f4.z += float12;
                            Transform transform1 = this.getWorldTransform(this.tempTransform);
                            transform1.origin.set(0.0F, 0.0F, 0.0F);
                            transform1.transform(vector3f4);
                            vector3f4.x = vector3f4.x + this.getX();
                            vector3f4.z = vector3f4.z + this.getY();
                            this.collideX = vector3f4.x;
                            this.collideY = vector3f4.z;
                            out.set(vector3f4.x, vector3f4.z);
                            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f4);
                            return out;
                        }
                    } else {
                        return null;
                    }
                }
            }
        }
    }

    public boolean testCollisionWithVehicle(BaseVehicle obj) {
        VehicleScript vehicleScript0 = this.script;
        if (vehicleScript0 == null) {
            vehicleScript0 = ScriptManager.instance.getVehicle(this.scriptName);
        }

        VehicleScript vehicleScript1 = obj.script;
        if (vehicleScript1 == null) {
            vehicleScript1 = ScriptManager.instance.getVehicle(obj.scriptName);
        }

        if (vehicleScript0 != null && vehicleScript1 != null) {
            Vector2[] vector20 = BaseVehicle.L_testCollisionWithVehicle.testVecs1;
            Vector2[] vector21 = BaseVehicle.L_testCollisionWithVehicle.testVecs2;
            if (vector20[0] == null) {
                for (int _int = 0; _int < vector20.length; _int++) {
                    vector20[_int] = new Vector2();
                    vector21[_int] = new Vector2();
                }
            }

            Vector3f vector3f0 = vehicleScript0.getExtents();
            Vector3f vector3f1 = vehicleScript0.getCenterOfMassOffset();
            Vector3f vector3f2 = vehicleScript1.getExtents();
            Vector3f vector3f3 = vehicleScript1.getCenterOfMassOffset();
            Vector3f vector3f4 = BaseVehicle.L_testCollisionWithVehicle.worldPos;
            float _float = 0.5F;
            this.getWorldPos(vector3f1.x + vector3f0.x * _float, 0.0F, vector3f1.z + vector3f0.z * _float, vector3f4, vehicleScript0);
            vector20[0].set(vector3f4.x, vector3f4.y);
            this.getWorldPos(vector3f1.x - vector3f0.x * _float, 0.0F, vector3f1.z + vector3f0.z * _float, vector3f4, vehicleScript0);
            vector20[1].set(vector3f4.x, vector3f4.y);
            this.getWorldPos(vector3f1.x - vector3f0.x * _float, 0.0F, vector3f1.z - vector3f0.z * _float, vector3f4, vehicleScript0);
            vector20[2].set(vector3f4.x, vector3f4.y);
            this.getWorldPos(vector3f1.x + vector3f0.x * _float, 0.0F, vector3f1.z - vector3f0.z * _float, vector3f4, vehicleScript0);
            vector20[3].set(vector3f4.x, vector3f4.y);
            obj.getWorldPos(vector3f3.x + vector3f2.x * _float, 0.0F, vector3f3.z + vector3f2.z * _float, vector3f4, vehicleScript1);
            vector21[0].set(vector3f4.x, vector3f4.y);
            obj.getWorldPos(vector3f3.x - vector3f2.x * _float, 0.0F, vector3f3.z + vector3f2.z * _float, vector3f4, vehicleScript1);
            vector21[1].set(vector3f4.x, vector3f4.y);
            obj.getWorldPos(vector3f3.x - vector3f2.x * _float, 0.0F, vector3f3.z - vector3f2.z * _float, vector3f4, vehicleScript1);
            vector21[2].set(vector3f4.x, vector3f4.y);
            obj.getWorldPos(vector3f3.x + vector3f2.x * _float, 0.0F, vector3f3.z - vector3f2.z * _float, vector3f4, vehicleScript1);
            vector21[3].set(vector3f4.x, vector3f4.y);
            return QuadranglesIntersection.IsQuadranglesAreIntersected(vector20, vector21);
        } else {
            return false;
        }
    }

    protected float getObjectX(IsoObject isoObject) {
        return isoObject instanceof IsoMovingObject ? isoObject.getX() : (float)isoObject.getSquare().getX() + 0.5F;
    }

    protected float getObjectY(IsoObject isoObject) {
        return isoObject instanceof IsoMovingObject ? isoObject.getY() : (float)isoObject.getSquare().getY() + 0.5F;
    }

    public void ApplyImpulse(IsoObject obj, float mul) {
        float float0 = this.getObjectX(obj);
        float float1 = this.getObjectY(obj);
        BaseVehicle.VehicleImpulse vehicleImpulse = BaseVehicle.VehicleImpulse.alloc();
        vehicleImpulse.impulse.set(this.x - float0, 0.0F, this.y - float1);
        vehicleImpulse.impulse.normalize();
        vehicleImpulse.impulse.mul(mul);
        vehicleImpulse.rel_pos.set(float0 - this.x, 0.0F, float1 - this.y);
        this.impulseFromHitZombie.add(vehicleImpulse);
    }

    public void ApplyImpulse4Break(IsoObject obj, float mul) {
        float float0 = this.getObjectX(obj);
        float float1 = this.getObjectY(obj);
        BaseVehicle.VehicleImpulse vehicleImpulse = BaseVehicle.VehicleImpulse.alloc();
        this.getLinearVelocity(vehicleImpulse.impulse);
        vehicleImpulse.impulse.mul(-mul * this.getFudgedMass());
        vehicleImpulse.rel_pos.set(float0 - this.x, 0.0F, float1 - this.y);
        this.impulseFromHitZombie.add(vehicleImpulse);
    }

    public void hitCharacter(IsoZombie chr) {
        IsoPlayer isoPlayer = Type.tryCastTo(chr, IsoPlayer.class);
        IsoZombie isoZombie = Type.tryCastTo(chr, IsoZombie.class);
        if (chr.getCurrentState() != StaggerBackState.instance() && chr.getCurrentState() != ZombieFallDownState.instance()) {
            if (!(Math.abs(chr.x - this.x) < 0.01F) && !(Math.abs(chr.y - this.y) < 0.01F)) {
                float float0 = 15.0F;
                Vector3f vector3f0 = this.getLinearVelocity(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                vector3f0.y = 0.0F;
                float float1 = vector3f0.length();
                float1 = Math.min(float1, float0);
                if (float1 < 0.05F) {
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                } else {
                    Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                    vector3f1.set(this.x - chr.x, 0.0F, this.y - chr.y);
                    vector3f1.normalize();
                    vector3f0.normalize();
                    float float2 = vector3f0.dot(vector3f1);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                    if (float2 < 0.0F && !GameServer.bServer) {
                        this.ApplyImpulse(chr, this.getFudgedMass() * 7.0F * float1 / float0 * Math.abs(float2));
                    }

                    vector3f1.normalize();
                    vector3f1.mul(3.0F * float1 / float0);
                    Vector2 vector2 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                    float float3 = float1 + this.physics.clientForce / this.getFudgedMass();
                    if (isoPlayer != null) {
                        isoPlayer.setVehicleHitLocation(this);
                    } else if (isoZombie != null) {
                        isoZombie.setVehicleHitLocation(this);
                    }

                    BaseSoundEmitter baseSoundEmitter = IsoWorld.instance.getFreeEmitter(chr.x, chr.y, chr.z);
                    long long0 = baseSoundEmitter.playSound("VehicleHitCharacter");
                    baseSoundEmitter.setParameterValue(long0, FMODManager.instance.getParameterDescription("VehicleSpeed"), this.getCurrentSpeedKmHour());
                    chr.Hit(this, float3, float2 > 0.0F, vector2.set(-vector3f1.x, -vector3f1.z));
                    ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector2);
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                    long long1 = System.currentTimeMillis();
                    long long2 = (long1 - this.zombieHitTimestamp) / 1000L;
                    this.zombiesHits = Math.max(this.zombiesHits - (int)long2, 0);
                    if (long1 - this.zombieHitTimestamp > 700L) {
                        this.zombieHitTimestamp = long1;
                        this.zombiesHits++;
                        this.zombiesHits = Math.min(this.zombiesHits, 20);
                    }

                    if (float1 >= 5.0F || this.zombiesHits > 10) {
                        float1 = this.getCurrentSpeedKmHour() / 5.0F;
                        Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                        this.getLocalPos(chr.x, chr.y, chr.z, vector3f2);
                        if (vector3f2.z > 0.0F) {
                            int int0 = this.caclulateDamageWithBodies(true);
                            this.addDamageFrontHitAChr(int0);
                        } else {
                            int int1 = this.caclulateDamageWithBodies(false);
                            this.addDamageRearHitAChr(int1);
                        }

                        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                    }
                }
            }
        }
    }

    private int caclulateDamageWithBodies(boolean boolean1) {
        boolean boolean0 = this.getCurrentSpeedKmHour() > 0.0F;
        float float0 = Math.abs(this.getCurrentSpeedKmHour());
        float float1 = float0 / 160.0F;
        float1 = PZMath.clamp(float1 * float1, 0.0F, 1.0F);
        float float2 = 60.0F * float1;
        float float3 = PZMath.max(1.0F, (float)this.zombiesHits / 3.0F);
        if (!boolean1 && !boolean0) {
            float3 = 1.0F;
        }

        if (this.zombiesHits > 10 && float2 < Math.abs(this.getCurrentSpeedKmHour()) / 5.0F) {
            float2 = Math.abs(this.getCurrentSpeedKmHour()) / 5.0F;
        }

        return (int)(float3 * float2);
    }

    public int calculateDamageWithCharacter(IsoGameCharacter chr) {
        Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        this.getLocalPos(chr.x, chr.y, chr.z, vector3f);
        int _int;
        if (vector3f.z > 0.0F) {
            _int = this.caclulateDamageWithBodies(true);
        } else {
            _int = -1 * this.caclulateDamageWithBodies(false);
        }

        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return _int;
    }

    public boolean blocked(int x, int y, int z) {
        if (this.removedFromWorld || this.current == null || this.getController() == null) {
            return false;
        } else if (this.getController() == null) {
            return false;
        } else if (z != (int)this.getZ()) {
            return false;
        } else if (IsoUtils.DistanceTo2D((float)x + 0.5F, (float)y + 0.5F, this.x, this.y) > 5.0F) {
            return false;
        } else {
            float float0 = 0.3F;
            Transform transform = this.tempTransform3;
            this.getWorldTransform(transform);
            transform.inverse();
            Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            vector3f0.set((float)x + 0.5F - WorldSimulation.instance.offsetX, 0.0F, (float)y + 0.5F - WorldSimulation.instance.offsetY);
            transform.transform(vector3f0);
            Vector3f vector3f1 = this.script.getExtents();
            Vector3f vector3f2 = this.script.getCenterOfMassOffset();
            float float1 = this.clamp(vector3f0.x, vector3f2.x - vector3f1.x / 2.0F, vector3f2.x + vector3f1.x / 2.0F);
            float float2 = this.clamp(vector3f0.z, vector3f2.z - vector3f1.z / 2.0F, vector3f2.z + vector3f1.z / 2.0F);
            float float3 = vector3f0.x - float1;
            float float4 = vector3f0.z - float2;
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
            float float5 = float3 * float3 + float4 * float4;
            return float5 < float0 * float0;
        }
    }

    public boolean isIntersectingSquare(int x, int y, int z) {
        if (z != (int)this.getZ()) {
            return false;
        } else if (!this.removedFromWorld && this.current != null && this.getController() != null) {
            tempPoly.x1 = tempPoly.x4 = (float)x;
            tempPoly.y1 = tempPoly.y2 = (float)y;
            tempPoly.x2 = tempPoly.x3 = (float)(x + 1);
            tempPoly.y3 = tempPoly.y4 = (float)(y + 1);
            return PolyPolyIntersect.intersects(tempPoly, this.getPoly());
        } else {
            return false;
        }
    }

    public boolean isIntersectingSquareWithShadow(int x, int y, int z) {
        if (z != (int)this.getZ()) {
            return false;
        } else if (!this.removedFromWorld && this.current != null && this.getController() != null) {
            tempPoly.x1 = tempPoly.x4 = (float)x;
            tempPoly.y1 = tempPoly.y2 = (float)y;
            tempPoly.x2 = tempPoly.x3 = (float)(x + 1);
            tempPoly.y3 = tempPoly.y4 = (float)(y + 1);
            return PolyPolyIntersect.intersects(tempPoly, this.shadowCoord);
        } else {
            return false;
        }
    }

    public boolean circleIntersects(float x, float y, float z, float radius) {
        if (this.getController() == null) {
            return false;
        } else if ((int)z != (int)this.getZ()) {
            return false;
        } else if (IsoUtils.DistanceTo2D(x, y, this.x, this.y) > 5.0F) {
            return false;
        } else {
            Vector3f vector3f0 = this.script.getExtents();
            Vector3f vector3f1 = this.script.getCenterOfMassOffset();
            Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            this.getLocalPos(x, y, z, vector3f2);
            float float0 = vector3f1.x - vector3f0.x / 2.0F;
            float float1 = vector3f1.x + vector3f0.x / 2.0F;
            float float2 = vector3f1.z - vector3f0.z / 2.0F;
            float float3 = vector3f1.z + vector3f0.z / 2.0F;
            if (vector3f2.x > float0 && vector3f2.x < float1 && vector3f2.z > float2 && vector3f2.z < float3) {
                return true;
            } else {
                float float4 = this.clamp(vector3f2.x, float0, float1);
                float float5 = this.clamp(vector3f2.z, float2, float3);
                float float6 = vector3f2.x - float4;
                float float7 = vector3f2.z - float5;
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
                float float8 = float6 * float6 + float7 * float7;
                return float8 < radius * radius;
            }
        }
    }

    public void updateLights() {
        VehicleModelInstance vehicleModelInstance = (VehicleModelInstance)this.sprite.modelSlot.model;
        vehicleModelInstance.textureRustA = this.rust;
        if (this.script.getWheelCount() == 0) {
            vehicleModelInstance.textureRustA = 0.0F;
        }

        vehicleModelInstance.painColor.x = this.colorHue;
        vehicleModelInstance.painColor.y = this.colorSaturation;
        vehicleModelInstance.painColor.z = this.colorValue;
        boolean boolean0 = false;
        boolean boolean1 = false;
        boolean boolean2 = false;
        boolean boolean3 = false;
        boolean boolean4 = false;
        boolean boolean5 = false;
        boolean boolean6 = false;
        boolean boolean7 = false;
        if (this.windowLightsOn) {
            VehiclePart vehiclePart0 = this.getPartById("Windshield");
            boolean0 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindshieldRear");
            boolean1 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindowFrontLeft");
            boolean2 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindowMiddleLeft");
            boolean3 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindowRearLeft");
            boolean4 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindowFrontRight");
            boolean5 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindowMiddleRight");
            boolean6 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
            vehiclePart0 = this.getPartById("WindowRearRight");
            boolean7 = vehiclePart0 != null && vehiclePart0.getInventoryItem() != null;
        }

        vehicleModelInstance.textureLightsEnables1[10] = boolean0 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables1[14] = boolean1 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables1[2] = boolean2 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables1[6] = boolean3 | boolean4 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables1[9] = boolean5 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables1[13] = boolean6 | boolean7 ? 1.0F : 0.0F;
        boolean boolean8 = false;
        boolean boolean9 = false;
        boolean boolean10 = false;
        boolean boolean11 = false;
        if (this.headlightsOn && this.getBatteryCharge() > 0.0F) {
            VehiclePart vehiclePart1 = this.getPartById("HeadlightLeft");
            if (vehiclePart1 != null && vehiclePart1.getInventoryItem() != null) {
                boolean8 = true;
            }

            vehiclePart1 = this.getPartById("HeadlightRight");
            if (vehiclePart1 != null && vehiclePart1.getInventoryItem() != null) {
                boolean9 = true;
            }

            vehiclePart1 = this.getPartById("HeadlightRearLeft");
            if (vehiclePart1 != null && vehiclePart1.getInventoryItem() != null) {
                boolean11 = true;
            }

            vehiclePart1 = this.getPartById("HeadlightRearRight");
            if (vehiclePart1 != null && vehiclePart1.getInventoryItem() != null) {
                boolean10 = true;
            }
        }

        vehicleModelInstance.textureLightsEnables2[4] = boolean9 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables2[8] = boolean8 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables2[12] = boolean10 ? 1.0F : 0.0F;
        vehicleModelInstance.textureLightsEnables2[1] = boolean11 ? 1.0F : 0.0F;
        boolean boolean12 = this.stoplightsOn && this.getBatteryCharge() > 0.0F;
        if (this.scriptName.contains("Trailer")
            && this.vehicleTowedBy != null
            && this.vehicleTowedBy.stoplightsOn
            && this.vehicleTowedBy.getBatteryCharge() > 0.0F) {
            boolean12 = true;
        }

        if (boolean12) {
            vehicleModelInstance.textureLightsEnables2[5] = 1.0F;
            vehicleModelInstance.textureLightsEnables2[9] = 1.0F;
        } else {
            vehicleModelInstance.textureLightsEnables2[5] = 0.0F;
            vehicleModelInstance.textureLightsEnables2[9] = 0.0F;
        }

        if (this.script.getLightbar().enable) {
            if (this.lightbarLightsMode.isEnable() && this.getBatteryCharge() > 0.0F) {
                switch (this.lightbarLightsMode.getLightTexIndex()) {
                    case 0:
                        vehicleModelInstance.textureLightsEnables2[13] = 0.0F;
                        vehicleModelInstance.textureLightsEnables2[2] = 0.0F;
                        break;
                    case 1:
                        vehicleModelInstance.textureLightsEnables2[13] = 0.0F;
                        vehicleModelInstance.textureLightsEnables2[2] = 1.0F;
                        break;
                    case 2:
                        vehicleModelInstance.textureLightsEnables2[13] = 1.0F;
                        vehicleModelInstance.textureLightsEnables2[2] = 0.0F;
                        break;
                    default:
                        vehicleModelInstance.textureLightsEnables2[13] = 0.0F;
                        vehicleModelInstance.textureLightsEnables2[2] = 0.0F;
                }
            } else {
                vehicleModelInstance.textureLightsEnables2[13] = 0.0F;
                vehicleModelInstance.textureLightsEnables2[2] = 0.0F;
            }
        }

        if (DebugOptions.instance.VehicleCycleColor.getValue()) {
            float float0 = (float)(System.currentTimeMillis() % 2000L);
            float float1 = (float)(System.currentTimeMillis() % 7000L);
            float float2 = (float)(System.currentTimeMillis() % 11000L);
            vehicleModelInstance.painColor.x = float0 / 2000.0F;
            vehicleModelInstance.painColor.y = float1 / 7000.0F;
            vehicleModelInstance.painColor.z = float2 / 11000.0F;
        }

        if (DebugOptions.instance.VehicleRenderBlood0.getValue()) {
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables2, 0.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables2, 0.0F);
        }

        if (DebugOptions.instance.VehicleRenderBlood50.getValue()) {
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables1, 0.5F);
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables2, 0.5F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables1, 1.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables2, 1.0F);
        }

        if (DebugOptions.instance.VehicleRenderBlood100.getValue()) {
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables1, 1.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables2, 1.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables1, 1.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables2, 1.0F);
        }

        if (DebugOptions.instance.VehicleRenderDamage0.getValue()) {
            Arrays.fill(vehicleModelInstance.textureDamage1Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.textureDamage1Enables2, 0.0F);
            Arrays.fill(vehicleModelInstance.textureDamage2Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.textureDamage2Enables2, 0.0F);
        }

        if (DebugOptions.instance.VehicleRenderDamage1.getValue()) {
            Arrays.fill(vehicleModelInstance.textureDamage1Enables1, 1.0F);
            Arrays.fill(vehicleModelInstance.textureDamage1Enables2, 1.0F);
            Arrays.fill(vehicleModelInstance.textureDamage2Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.textureDamage2Enables2, 0.0F);
        }

        if (DebugOptions.instance.VehicleRenderDamage2.getValue()) {
            Arrays.fill(vehicleModelInstance.textureDamage1Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.textureDamage1Enables2, 0.0F);
            Arrays.fill(vehicleModelInstance.textureDamage2Enables1, 1.0F);
            Arrays.fill(vehicleModelInstance.textureDamage2Enables2, 1.0F);
        }

        if (DebugOptions.instance.VehicleRenderRust0.getValue()) {
            vehicleModelInstance.textureRustA = 0.0F;
        }

        if (DebugOptions.instance.VehicleRenderRust50.getValue()) {
            vehicleModelInstance.textureRustA = 0.5F;
        }

        if (DebugOptions.instance.VehicleRenderRust100.getValue()) {
            vehicleModelInstance.textureRustA = 1.0F;
        }

        vehicleModelInstance.refBody = 0.3F;
        vehicleModelInstance.refWindows = 0.4F;
        if (this.rust > 0.8F) {
            vehicleModelInstance.refBody = 0.1F;
            vehicleModelInstance.refWindows = 0.2F;
        }
    }

    private void updateWorldLights() {
        if (!this.script.getLightbar().enable) {
            this.removeWorldLights();
        } else if (!this.lightbarLightsMode.isEnable() || this.getBatteryCharge() <= 0.0F) {
            this.removeWorldLights();
        } else if (this.lightbarLightsMode.getLightTexIndex() == 0) {
            this.removeWorldLights();
        } else {
            this.leftLight1.radius = this.leftLight2.radius = this.rightLight1.radius = this.rightLight2.radius = 8;
            if (this.lightbarLightsMode.getLightTexIndex() == 1) {
                Vector3f vector3f0 = this.getWorldPos(0.4F, 0.0F, 0.0F, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                int int0 = (int)vector3f0.x;
                int int1 = (int)vector3f0.y;
                int int2 = (int)(this.getZ() + 1.0F);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
                int int3 = this.leftLightIndex;
                if (int3 == 1 && this.leftLight1.x == int0 && this.leftLight1.y == int1 && this.leftLight1.z == int2) {
                    return;
                }

                if (int3 == 2 && this.leftLight2.x == int0 && this.leftLight2.y == int1 && this.leftLight2.z == int2) {
                    return;
                }

                this.removeWorldLights();
                IsoLightSource isoLightSource0;
                if (int3 == 1) {
                    isoLightSource0 = this.leftLight2;
                    this.leftLightIndex = 2;
                } else {
                    isoLightSource0 = this.leftLight1;
                    this.leftLightIndex = 1;
                }

                isoLightSource0.life = -1;
                isoLightSource0.x = int0;
                isoLightSource0.y = int1;
                isoLightSource0.z = int2;
                IsoWorld.instance.CurrentCell.addLamppost(isoLightSource0);
            } else {
                Vector3f vector3f1 = this.getWorldPos(-0.4F, 0.0F, 0.0F, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                int int4 = (int)vector3f1.x;
                int int5 = (int)vector3f1.y;
                int int6 = (int)(this.getZ() + 1.0F);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
                int int7 = this.rightLightIndex;
                if (int7 == 1 && this.rightLight1.x == int4 && this.rightLight1.y == int5 && this.rightLight1.z == int6) {
                    return;
                }

                if (int7 == 2 && this.rightLight2.x == int4 && this.rightLight2.y == int5 && this.rightLight2.z == int6) {
                    return;
                }

                this.removeWorldLights();
                IsoLightSource isoLightSource1;
                if (int7 == 1) {
                    isoLightSource1 = this.rightLight2;
                    this.rightLightIndex = 2;
                } else {
                    isoLightSource1 = this.rightLight1;
                    this.rightLightIndex = 1;
                }

                isoLightSource1.life = -1;
                isoLightSource1.x = int4;
                isoLightSource1.y = int5;
                isoLightSource1.z = int6;
                IsoWorld.instance.CurrentCell.addLamppost(isoLightSource1);
            }
        }
    }

    public void fixLightbarModelLighting(IsoLightSource isoLightSource, Vector3f vector3f) {
        if (isoLightSource == this.leftLight1 || isoLightSource == this.leftLight2) {
            vector3f.set(1.0F, 0.0F, 0.0F);
        } else if (isoLightSource == this.rightLight1 || isoLightSource == this.rightLight2) {
            vector3f.set(-1.0F, 0.0F, 0.0F);
        }
    }

    private void removeWorldLights() {
        if (this.leftLightIndex == 1) {
            IsoWorld.instance.CurrentCell.removeLamppost(this.leftLight1);
            this.leftLightIndex = -1;
        }

        if (this.leftLightIndex == 2) {
            IsoWorld.instance.CurrentCell.removeLamppost(this.leftLight2);
            this.leftLightIndex = -1;
        }

        if (this.rightLightIndex == 1) {
            IsoWorld.instance.CurrentCell.removeLamppost(this.rightLight1);
            this.rightLightIndex = -1;
        }

        if (this.rightLightIndex == 2) {
            IsoWorld.instance.CurrentCell.removeLamppost(this.rightLight2);
            this.rightLightIndex = -1;
        }
    }

    public void doDamageOverlay() {
        if (this.sprite.modelSlot != null) {
            this.doDoorDamage();
            this.doWindowDamage();
            this.doOtherBodyWorkDamage();
            this.doBloodOverlay();
        }
    }

    private void checkDamage(VehiclePart vehiclePart, int _int, boolean _boolean) {
        if (_boolean && vehiclePart != null && vehiclePart.getId().startsWith("Window") && vehiclePart.getScriptModelById("Default") != null) {
            _boolean = false;
        }

        VehicleModelInstance vehicleModelInstance = (VehicleModelInstance)this.sprite.modelSlot.model;

        try {
            vehicleModelInstance.textureDamage1Enables1[_int] = 0.0F;
            vehicleModelInstance.textureDamage2Enables1[_int] = 0.0F;
            vehicleModelInstance.textureUninstall1[_int] = 0.0F;
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                if (vehiclePart.getInventoryItem().getCondition() < 60 && vehiclePart.getInventoryItem().getCondition() >= 40) {
                    vehicleModelInstance.textureDamage1Enables1[_int] = 1.0F;
                }

                if (vehiclePart.getInventoryItem().getCondition() < 40) {
                    vehicleModelInstance.textureDamage2Enables1[_int] = 1.0F;
                }

                if (vehiclePart.window != null && vehiclePart.window.isOpen() && _boolean) {
                    vehicleModelInstance.textureUninstall1[_int] = 1.0F;
                }
            } else if (vehiclePart != null && _boolean) {
                vehicleModelInstance.textureUninstall1[_int] = 1.0F;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    private void checkDamage2(VehiclePart vehiclePart, int _int, boolean _boolean) {
        VehicleModelInstance vehicleModelInstance = (VehicleModelInstance)this.sprite.modelSlot.model;

        try {
            vehicleModelInstance.textureDamage1Enables2[_int] = 0.0F;
            vehicleModelInstance.textureDamage2Enables2[_int] = 0.0F;
            vehicleModelInstance.textureUninstall2[_int] = 0.0F;
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                if (vehiclePart.getInventoryItem().getCondition() < 60 && vehiclePart.getInventoryItem().getCondition() >= 40) {
                    vehicleModelInstance.textureDamage1Enables2[_int] = 1.0F;
                }

                if (vehiclePart.getInventoryItem().getCondition() < 40) {
                    vehicleModelInstance.textureDamage2Enables2[_int] = 1.0F;
                }

                if (vehiclePart.window != null && vehiclePart.window.isOpen() && _boolean) {
                    vehicleModelInstance.textureUninstall2[_int] = 1.0F;
                }
            } else if (vehiclePart != null && _boolean) {
                vehicleModelInstance.textureUninstall2[_int] = 1.0F;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    private void checkUninstall2(VehiclePart vehiclePart, int _int) {
        VehicleModelInstance vehicleModelInstance = (VehicleModelInstance)this.sprite.modelSlot.model;

        try {
            vehicleModelInstance.textureUninstall2[_int] = 0.0F;
            if (vehiclePart != null && vehiclePart.getInventoryItem() == null) {
                vehicleModelInstance.textureUninstall2[_int] = 1.0F;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    private void doOtherBodyWorkDamage() {
        this.checkDamage(this.getPartById("EngineDoor"), 0, false);
        this.checkDamage(this.getPartById("EngineDoor"), 3, false);
        this.checkDamage(this.getPartById("EngineDoor"), 11, false);
        this.checkDamage2(this.getPartById("EngineDoor"), 6, true);
        this.checkDamage(this.getPartById("TruckBed"), 4, false);
        this.checkDamage(this.getPartById("TruckBed"), 7, false);
        this.checkDamage(this.getPartById("TruckBed"), 15, false);
        VehiclePart vehiclePart = this.getPartById("TrunkDoor");
        if (vehiclePart != null) {
            this.checkDamage2(vehiclePart, 10, true);
            if (vehiclePart.scriptPart.hasLightsRear) {
                this.checkUninstall2(vehiclePart, 12);
                this.checkUninstall2(vehiclePart, 1);
                this.checkUninstall2(vehiclePart, 5);
                this.checkUninstall2(vehiclePart, 9);
            }
        } else {
            vehiclePart = this.getPartById("DoorRear");
            if (vehiclePart != null) {
                this.checkDamage2(vehiclePart, 10, true);
                if (vehiclePart.scriptPart.hasLightsRear) {
                    this.checkUninstall2(vehiclePart, 12);
                    this.checkUninstall2(vehiclePart, 1);
                    this.checkUninstall2(vehiclePart, 5);
                    this.checkUninstall2(vehiclePart, 9);
                }
            }
        }
    }

    private void doWindowDamage() {
        this.checkDamage(this.getPartById("WindowFrontLeft"), 2, true);
        this.checkDamage(this.getPartById("WindowFrontRight"), 9, true);
        VehiclePart vehiclePart = this.getPartById("WindowRearLeft");
        if (vehiclePart != null) {
            this.checkDamage(vehiclePart, 6, true);
        } else {
            vehiclePart = this.getPartById("WindowMiddleLeft");
            if (vehiclePart != null) {
                this.checkDamage(vehiclePart, 6, true);
            }
        }

        vehiclePart = this.getPartById("WindowRearRight");
        if (vehiclePart != null) {
            this.checkDamage(vehiclePart, 13, true);
        } else {
            vehiclePart = this.getPartById("WindowMiddleRight");
            if (vehiclePart != null) {
                this.checkDamage(vehiclePart, 13, true);
            }
        }

        this.checkDamage(this.getPartById("Windshield"), 10, true);
        this.checkDamage(this.getPartById("WindshieldRear"), 14, true);
    }

    private void doDoorDamage() {
        this.checkDamage(this.getPartById("DoorFrontLeft"), 1, true);
        this.checkDamage(this.getPartById("DoorFrontRight"), 8, true);
        VehiclePart vehiclePart = this.getPartById("DoorRearLeft");
        if (vehiclePart != null) {
            this.checkDamage(vehiclePart, 5, true);
        } else {
            vehiclePart = this.getPartById("DoorMiddleLeft");
            if (vehiclePart != null) {
                this.checkDamage(vehiclePart, 5, true);
            }
        }

        vehiclePart = this.getPartById("DoorRearRight");
        if (vehiclePart != null) {
            this.checkDamage(vehiclePart, 12, true);
        } else {
            vehiclePart = this.getPartById("DoorMiddleRight");
            if (vehiclePart != null) {
                this.checkDamage(vehiclePart, 12, true);
            }
        }
    }

    public float getBloodIntensity(String id) {
        return (float)((Byte)this.bloodIntensity.getOrDefault(id, BYTE_ZERO) & 255) / 100.0F;
    }

    public void setBloodIntensity(String id, float intensity) {
        byte _byte = (byte)((int)(PZMath.clamp(intensity, 0.0F, 1.0F) * 100.0F));
        if (!this.bloodIntensity.containsKey(id) || _byte != (Byte)this.bloodIntensity.get(id)) {
            this.bloodIntensity.put(id, _byte);
            this.doBloodOverlay();
            this.transmitBlood();
        }
    }

    public void transmitBlood() {
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 4096);
        }
    }

    public void doBloodOverlay() {
        if (this.sprite.modelSlot != null) {
            VehicleModelInstance vehicleModelInstance = (VehicleModelInstance)this.sprite.modelSlot.model;
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood1Enables2, 0.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables1, 0.0F);
            Arrays.fill(vehicleModelInstance.matrixBlood2Enables2, 0.0F);
            if (Core.getInstance().getOptionBloodDecals() != 0) {
                this.doBloodOverlayFront(vehicleModelInstance.matrixBlood1Enables1, vehicleModelInstance.matrixBlood1Enables2, this.getBloodIntensity("Front"));
                this.doBloodOverlayRear(vehicleModelInstance.matrixBlood1Enables1, vehicleModelInstance.matrixBlood1Enables2, this.getBloodIntensity("Rear"));
                this.doBloodOverlayLeft(vehicleModelInstance.matrixBlood1Enables1, vehicleModelInstance.matrixBlood1Enables2, this.getBloodIntensity("Left"));
                this.doBloodOverlayRight(vehicleModelInstance.matrixBlood1Enables1, vehicleModelInstance.matrixBlood1Enables2, this.getBloodIntensity("Right"));

                for (Entry entry : this.bloodIntensity.entrySet()) {
                    Integer integer = (Integer)s_PartToMaskMap.get(entry.getKey());
                    if (integer != null) {
                        vehicleModelInstance.matrixBlood1Enables1[integer] = (float)((Byte)entry.getValue() & 255) / 100.0F;
                    }
                }

                this.doBloodOverlayAux(vehicleModelInstance.matrixBlood2Enables1, vehicleModelInstance.matrixBlood2Enables2, 1.0F);
            }
        }
    }

    private void doBloodOverlayAux(float[] float1, float[] float2, float float0) {
        float1[0] = float0;
        float2[6] = float0;
        float2[4] = float0;
        float2[8] = float0;
        float1[4] = float0;
        float1[7] = float0;
        float1[15] = float0;
        float2[10] = float0;
        float2[12] = float0;
        float2[1] = float0;
        float2[5] = float0;
        float2[9] = float0;
        float1[3] = float0;
        float1[8] = float0;
        float1[12] = float0;
        float1[11] = float0;
        float1[1] = float0;
        float1[5] = float0;
        float2[0] = float0;
        float1[10] = float0;
        float1[14] = float0;
        float1[9] = float0;
        float1[13] = float0;
        float1[2] = float0;
        float1[6] = float0;
    }

    private void doBloodOverlayFront(float[] float1, float[] float2, float float0) {
        float1[0] = float0;
        float2[6] = float0;
        float2[4] = float0;
        float2[8] = float0;
        float1[10] = float0;
    }

    private void doBloodOverlayRear(float[] float1, float[] float2, float float0) {
        float1[4] = float0;
        float2[10] = float0;
        float2[12] = float0;
        float2[1] = float0;
        float2[5] = float0;
        float2[9] = float0;
        float1[14] = float0;
    }

    private void doBloodOverlayLeft(float[] float1, float[] var2, float float0) {
        float1[11] = float0;
        float1[1] = float0;
        float1[5] = float0;
        float1[15] = float0;
        float1[2] = float0;
        float1[6] = float0;
    }

    private void doBloodOverlayRight(float[] float1, float[] var2, float float0) {
        float1[3] = float0;
        float1[8] = float0;
        float1[12] = float0;
        float1[7] = float0;
        float1[9] = float0;
        float1[13] = float0;
    }

    @Override
    public void render(float x, float y, float z, ColorInfo col, boolean bDoAttached, boolean bWallLightingPass, Shader shader) {
        if (this.script != null) {
            if (this.physics != null) {
                this.physics.debug();
            }

            int _int = IsoCamera.frameState.playerIndex;
            boolean boolean0 = IsoCamera.CamCharacter != null && IsoCamera.CamCharacter.getVehicle() == this;
            if (boolean0 || this.square.lighting[_int].bSeen()) {
                if (!boolean0 && !this.square.lighting[_int].bCouldSee()) {
                    this.setTargetAlpha(_int, 0.0F);
                } else {
                    this.setTargetAlpha(_int, 1.0F);
                }

                if (this.sprite.hasActiveModel()) {
                    this.updateLights();
                    boolean boolean1 = Core.getInstance().getOptionBloodDecals() != 0;
                    if (this.OptionBloodDecals != boolean1) {
                        this.OptionBloodDecals = boolean1;
                        this.doBloodOverlay();
                    }

                    col.a = this.getAlpha(_int);
                    inf.a = col.a;
                    inf.r = col.r;
                    inf.g = col.g;
                    inf.b = col.b;
                    this.sprite.renderVehicle(this.def, this, x, y, 0.0F, 0.0F, 0.0F, inf, true);
                }

                this.updateAlpha(_int);
                if (Core.bDebug && DebugOptions.instance.VehicleRenderArea.getValue()) {
                    this.renderAreas();
                }

                if (Core.bDebug && DebugOptions.instance.VehicleRenderAttackPositions.getValue()) {
                    this.m_surroundVehicle.render();
                }

                if (Core.bDebug && DebugOptions.instance.VehicleRenderExit.getValue()) {
                    this.renderExits();
                }

                if (Core.bDebug && DebugOptions.instance.VehicleRenderIntersectedSquares.getValue()) {
                    this.renderIntersectedSquares();
                }

                if (Core.bDebug && DebugOptions.instance.VehicleRenderAuthorizations.getValue()) {
                    this.renderAuthorizations();
                }

                if (Core.bDebug && DebugOptions.instance.VehicleRenderInterpolateBuffer.getValue()) {
                    this.renderInterpolateBuffer();
                }

                if (DebugOptions.instance.VehicleRenderTrailerPositions.getValue()) {
                    this.renderTrailerPositions();
                }

                this.renderUsableArea();
            }
        }
    }

    @Override
    public void renderlast() {
        int int0 = IsoCamera.frameState.playerIndex;

        for (int int1 = 0; int1 < this.parts.size(); int1++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(int1);
            if (vehiclePart.chatElement != null && vehiclePart.chatElement.getHasChatToDisplay()) {
                if (vehiclePart.getDeviceData() != null && !vehiclePart.getDeviceData().getIsTurnedOn()) {
                    vehiclePart.chatElement.clear(int0);
                } else {
                    float float0 = IsoUtils.XToScreen(this.getX(), this.getY(), this.getZ(), 0);
                    float float1 = IsoUtils.YToScreen(this.getX(), this.getY(), this.getZ(), 0);
                    float0 = float0 - IsoCamera.getOffX() - this.offsetX;
                    float1 = float1 - IsoCamera.getOffY() - this.offsetY;
                    float0 += (float)(32 * Core.TileScale);
                    float1 += (float)(20 * Core.TileScale);
                    float0 /= Core.getInstance().getZoom(int0);
                    float1 /= Core.getInstance().getZoom(int0);
                    vehiclePart.chatElement.renderBatched(int0, (int)float0, (int)float1);
                }
            }
        }
    }

    public void renderShadow() {
        if (this.physics != null) {
            if (this.script != null) {
                int _int = IsoCamera.frameState.playerIndex;
                if (this.square.lighting[_int].bSeen()) {
                    if (this.square.lighting[_int].bCouldSee()) {
                        this.setTargetAlpha(_int, 1.0F);
                    } else {
                        this.setTargetAlpha(_int, 0.0F);
                    }

                    Texture texture = this.getShadowTexture();
                    if (texture != null && this.getCurrentSquare() != null) {
                        float _float = 0.6F * this.getAlpha(_int);
                        ColorInfo colorInfo = this.getCurrentSquare().lighting[_int].lightInfo();
                        _float *= (colorInfo.r + colorInfo.g + colorInfo.b) / 3.0F;
                        if (this.polyDirty) {
                            this.getPoly();
                        }

                        SpriteRenderer.instance
                            .renderPoly(
                                texture,
                                (float)((int)IsoUtils.XToScreenExact(this.shadowCoord.x2, this.shadowCoord.y2, 0.0F, 0)),
                                (float)((int)IsoUtils.YToScreenExact(this.shadowCoord.x2, this.shadowCoord.y2, 0.0F, 0)),
                                (float)((int)IsoUtils.XToScreenExact(this.shadowCoord.x1, this.shadowCoord.y1, 0.0F, 0)),
                                (float)((int)IsoUtils.YToScreenExact(this.shadowCoord.x1, this.shadowCoord.y1, 0.0F, 0)),
                                (float)((int)IsoUtils.XToScreenExact(this.shadowCoord.x4, this.shadowCoord.y4, 0.0F, 0)),
                                (float)((int)IsoUtils.YToScreenExact(this.shadowCoord.x4, this.shadowCoord.y4, 0.0F, 0)),
                                (float)((int)IsoUtils.XToScreenExact(this.shadowCoord.x3, this.shadowCoord.y3, 0.0F, 0)),
                                (float)((int)IsoUtils.YToScreenExact(this.shadowCoord.x3, this.shadowCoord.y3, 0.0F, 0)),
                                1.0F,
                                1.0F,
                                1.0F,
                                0.8F * _float
                            );
                    }
                }
            }
        }
    }

    public boolean isEnterBlocked(IsoGameCharacter chr, int seat) {
        return this.isExitBlocked(chr, seat);
    }

    public boolean isExitBlocked(int seat) {
        VehicleScript.Position position0 = this.getPassengerPosition(seat, "inside");
        VehicleScript.Position position1 = this.getPassengerPosition(seat, "outside");
        if (position0 != null && position1 != null) {
            Vector3f vector3f0 = this.getPassengerPositionWorldPos(position1, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            if (position1.area != null) {
                Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                VehicleScript.Area area = this.script.getAreaById(position1.area);
                Vector2 vector21 = this.areaPositionWorld4PlayerInteract(area, vector20);
                if (vector21 != null) {
                    vector3f0.x = vector21.x;
                    vector3f0.y = vector21.y;
                }

                ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
            }

            vector3f0.z = 0.0F;
            Vector3f vector3f1 = this.getPassengerPositionWorldPos(position0, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            boolean _boolean = PolygonalMap2.instance.lineClearCollide(vector3f1.x, vector3f1.y, vector3f0.x, vector3f0.y, (int)this.z, this, false, false);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
            return _boolean;
        } else {
            return true;
        }
    }

    public boolean isExitBlocked(IsoGameCharacter chr, int seat) {
        VehicleScript.Position position0 = this.getPassengerPosition(seat, "inside");
        VehicleScript.Position position1 = this.getPassengerPosition(seat, "outside");
        if (position0 != null && position1 != null) {
            Vector3f vector3f0 = this.getPassengerPositionWorldPos(position1, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            if (position1.area != null) {
                Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                VehicleScript.Area area = this.script.getAreaById(position1.area);
                Vector2 vector21 = this.areaPositionWorld4PlayerInteract(area, vector20);
                if (vector21 != null) {
                    vector3f0.x = vector21.x;
                    vector3f0.y = vector21.y;
                }

                ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
            }

            vector3f0.z = 0.0F;
            Vector3f vector3f1 = this.getPassengerPositionWorldPos(position0, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            boolean _boolean = PolygonalMap2.instance.lineClearCollide(vector3f1.x, vector3f1.y, vector3f0.x, vector3f0.y, (int)this.z, this, false, false);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
            if (!_boolean && GameClient.bClient) {
                IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)vector3f0.x, (double)vector3f0.y, (double)vector3f0.z);
                if (isoGridSquare != null && chr instanceof IsoPlayer && !SafeHouse.isPlayerAllowedOnSquare((IsoPlayer)chr, isoGridSquare)) {
                    _boolean = true;
                }
            }

            return _boolean;
        } else {
            return true;
        }
    }

    public boolean isPassengerUseDoor2(IsoGameCharacter chr, int seat) {
        VehicleScript.Position position = this.getPassengerPosition(seat, "outside2");
        if (position != null) {
            Vector3f vector3f = this.getPassengerPositionWorldPos(position, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            vector3f.sub(chr.x, chr.y, chr.z);
            float _float = vector3f.length();
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            if (_float < 2.0F) {
                return true;
            }
        }

        return false;
    }

    public boolean isEnterBlocked2(IsoGameCharacter chr, int seat) {
        return this.isExitBlocked2(seat);
    }

    public boolean isExitBlocked2(int seat) {
        VehicleScript.Position position0 = this.getPassengerPosition(seat, "inside");
        VehicleScript.Position position1 = this.getPassengerPosition(seat, "outside2");
        if (position0 != null && position1 != null) {
            Vector3f vector3f0 = this.getPassengerPositionWorldPos(position1, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            vector3f0.z = 0.0F;
            Vector3f vector3f1 = this.getPassengerPositionWorldPos(position0, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            boolean _boolean = PolygonalMap2.instance.lineClearCollide(vector3f1.x, vector3f1.y, vector3f0.x, vector3f0.y, (int)this.z, this, false, false);
            IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)vector3f0.x, (double)vector3f0.y, (double)vector3f0.z);
            IsoGameCharacter isoGameCharacter = this.getCharacter(seat);
            if (isoGameCharacter instanceof IsoPlayer && !SafeHouse.isPlayerAllowedOnSquare((IsoPlayer)isoGameCharacter, isoGridSquare)) {
                _boolean = true;
            }

            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
            return _boolean;
        } else {
            return true;
        }
    }

    private void renderExits() {
        int int0 = Core.TileScale;
        Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();

        for (int int1 = 0; int1 < this.getMaxPassengers(); int1++) {
            VehicleScript.Position position0 = this.getPassengerPosition(int1, "inside");
            VehicleScript.Position position1 = this.getPassengerPosition(int1, "outside");
            if (position0 != null && position1 != null) {
                float float0 = 0.3F;
                this.getPassengerPositionWorldPos(position1, vector3f0);
                this.getPassengerPositionWorldPos(position0, vector3f1);
                int int2 = (int)Math.floor((double)(vector3f0.x - float0));
                int int3 = (int)Math.floor((double)(vector3f0.x + float0));
                int int4 = (int)Math.floor((double)(vector3f0.y - float0));
                int int5 = (int)Math.floor((double)(vector3f0.y + float0));

                for (int int6 = int4; int6 <= int5; int6++) {
                    for (int int7 = int2; int7 <= int3; int7++) {
                        int int8 = (int)IsoUtils.XToScreenExact((float)int7, (float)(int6 + 1), (float)((int)this.z), 0);
                        int int9 = (int)IsoUtils.YToScreenExact((float)int7, (float)(int6 + 1), (float)((int)this.z), 0);
                        SpriteRenderer.instance
                            .renderPoly(
                                (float)int8,
                                (float)int9,
                                (float)(int8 + 32 * int0),
                                (float)(int9 - 16 * int0),
                                (float)(int8 + 64 * int0),
                                (float)int9,
                                (float)(int8 + 32 * int0),
                                (float)(int9 + 16 * int0),
                                1.0F,
                                1.0F,
                                1.0F,
                                0.5F
                            );
                    }
                }

                float float1 = 1.0F;
                float float2 = 1.0F;
                float float3 = 1.0F;
                if (this.isExitBlocked(int1)) {
                    float3 = 0.0F;
                    float2 = 0.0F;
                }

                this.getController().drawCircle(vector3f1.x, vector3f1.y, float0, 0.0F, 0.0F, 1.0F, 1.0F);
                this.getController().drawCircle(vector3f0.x, vector3f0.y, float0, float1, float2, float3, 1.0F);
            }
        }

        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
    }

    private Vector2 areaPositionLocal(VehicleScript.Area area) {
        return this.areaPositionLocal(area, new Vector2());
    }

    private Vector2 areaPositionLocal(VehicleScript.Area area, Vector2 vector21) {
        Vector2 vector20 = this.areaPositionWorld(area, vector21);
        Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        this.getLocalPos(vector20.x, vector20.y, 0.0F, vector3f);
        vector20.set(vector3f.x, vector3f.z);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        return vector20;
    }

    public Vector2 areaPositionWorld(VehicleScript.Area area) {
        return this.areaPositionWorld(area, new Vector2());
    }

    public Vector2 areaPositionWorld(VehicleScript.Area area, Vector2 out) {
        if (area == null) {
            return null;
        } else {
            Vector3f vector3f = this.getWorldPos(area.x, 0.0F, area.y, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            out.set(vector3f.x, vector3f.y);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            return out;
        }
    }

    public Vector2 areaPositionWorld4PlayerInteract(VehicleScript.Area area) {
        return this.areaPositionWorld4PlayerInteract(area, new Vector2());
    }

    public Vector2 areaPositionWorld4PlayerInteract(VehicleScript.Area area, Vector2 out) {
        Vector3f vector3f0 = this.script.getExtents();
        Vector3f vector3f1 = this.script.getCenterOfMassOffset();
        Vector2 vector2 = this.areaPositionWorld(area, out);
        Vector3f vector3f2 = this.getLocalPos(vector2.x, vector2.y, 0.0F, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        if (!(area.x > vector3f1.x + vector3f0.x / 2.0F) && !(area.x < vector3f1.x - vector3f0.x / 2.0F)) {
            if (area.y > 0.0F) {
                vector3f2.z = vector3f2.z - area.h * 0.3F;
            } else {
                vector3f2.z = vector3f2.z + area.h * 0.3F;
            }
        } else if (area.x > 0.0F) {
            vector3f2.x = vector3f2.x - area.w * 0.3F;
        } else {
            vector3f2.x = vector3f2.x + area.w * 0.3F;
        }

        this.getWorldPos(vector3f2, vector3f2);
        out.set(vector3f2.x, vector3f2.y);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
        return out;
    }

    private void renderAreas() {
        if (this.getScript() != null) {
            Vector3f vector3f = this.getForwardVector(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();

            for (int _int = 0; _int < this.parts.size(); _int++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                if (vehiclePart.getArea() != null) {
                    VehicleScript.Area area = this.getScript().getAreaById(vehiclePart.getArea());
                    if (area != null) {
                        Vector2 vector21 = this.areaPositionWorld(area, vector20);
                        if (vector21 != null) {
                            boolean _boolean = this.isInArea(area.id, IsoPlayer.getInstance());
                            this.getController()
                                .drawRect(
                                    vector3f,
                                    vector21.x - WorldSimulation.instance.offsetX,
                                    vector21.y - WorldSimulation.instance.offsetY,
                                    area.w,
                                    area.h / 2.0F,
                                    _boolean ? 0.0F : 0.65F,
                                    _boolean ? 1.0F : 0.65F,
                                    _boolean ? 1.0F : 0.65F
                                );
                            vector21 = this.areaPositionWorld4PlayerInteract(area, vector20);
                            this.getController()
                                .drawRect(
                                    vector3f,
                                    vector21.x - WorldSimulation.instance.offsetX,
                                    vector21.y - WorldSimulation.instance.offsetY,
                                    0.1F,
                                    0.1F,
                                    1.0F,
                                    0.0F,
                                    0.0F
                                );
                        }
                    }
                }
            }

            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
                IsoUtils.XToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
                1.0F,
                0.5F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
                IsoUtils.XToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
                1.0F,
                0.5F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
                IsoUtils.XToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
                1.0F,
                0.5F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
                IsoUtils.XToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
                IsoUtils.YToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
                1.0F,
                0.5F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.shadowCoord.x1, this.shadowCoord.y1, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x1, this.shadowCoord.y1, 0.0F, 0),
                IsoUtils.XToScreenExact(this.shadowCoord.x2, this.shadowCoord.y2, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x2, this.shadowCoord.y2, 0.0F, 0),
                0.5F,
                1.0F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.shadowCoord.x2, this.shadowCoord.y2, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x2, this.shadowCoord.y2, 0.0F, 0),
                IsoUtils.XToScreenExact(this.shadowCoord.x3, this.shadowCoord.y3, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x3, this.shadowCoord.y3, 0.0F, 0),
                0.5F,
                1.0F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.shadowCoord.x3, this.shadowCoord.y3, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x3, this.shadowCoord.y3, 0.0F, 0),
                IsoUtils.XToScreenExact(this.shadowCoord.x4, this.shadowCoord.y4, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x4, this.shadowCoord.y4, 0.0F, 0),
                0.5F,
                1.0F,
                0.5F,
                1.0F,
                0
            );
            LineDrawer.drawLine(
                IsoUtils.XToScreenExact(this.shadowCoord.x4, this.shadowCoord.y4, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x4, this.shadowCoord.y4, 0.0F, 0),
                IsoUtils.XToScreenExact(this.shadowCoord.x1, this.shadowCoord.y1, 0.0F, 0),
                IsoUtils.YToScreenExact(this.shadowCoord.x1, this.shadowCoord.y1, 0.0F, 0),
                0.5F,
                1.0F,
                0.5F,
                1.0F,
                0
            );
        }
    }

    private void renderInterpolateBuffer() {
        if (this.netPlayerAuthorization == BaseVehicle.Authorization.Remote) {
            float float0 = IsoUtils.XToScreenExact(this.x, this.y, 0.0F, 0);
            float float1 = IsoUtils.YToScreenExact(this.x, this.y, 0.0F, 0);
            float float2 = float0 - 310.0F;
            float float3 = float1 + 22.0F;
            float float4 = 300.0F;
            float float5 = 150.0F;
            float float6 = 4.0F;
            Color color0 = Color.lightGray;
            Color color1 = Color.green;
            Color color2 = Color.cyan;
            Color color3 = Color.yellow;
            Color color4 = Color.blue;
            Color color5 = Color.red;
            LineDrawer.drawLine(float2, float3, float2 + float4, float3, color0.r, color0.g, color0.b, color0.a, 1);
            LineDrawer.drawLine(float2, float3 + float5, float2 + float4, float3 + float5, color0.r, color0.g, color0.b, color0.a, 1);
            long long0 = zombie.GameTime.getServerTimeMills();
            long long1 = long0 - 150L - (long)this.interpolation.history;
            long long2 = long0 + 150L;
            this.renderInterpolateBuffer_drawVertLine(long1, color0, float2, float3, float4, float5, long1, long2, true);
            this.renderInterpolateBuffer_drawVertLine(long2, color0, float2, float3, float4, float5, long1, long2, true);
            this.renderInterpolateBuffer_drawVertLine(long0, color1, float2, float3, float4, float5, long1, long2, true);
            this.renderInterpolateBuffer_drawVertLine(long0 - (long)this.interpolation.delay, color2, float2, float3, float4, float5, long1, long2, true);
            this.renderInterpolateBuffer_drawPoint(
                long0 - (long)this.interpolation.delay, this.x, color4, 5, float2, float3, float4, float5, long1, long2, this.x - float6, this.x + float6
            );
            this.renderInterpolateBuffer_drawPoint(
                long0 - (long)this.interpolation.delay, this.y, color5, 5, float2, float3, float4, float5, long1, long2, this.y - float6, this.y + float6
            );
            long long3 = 0L;
            float float7 = Float.NaN;
            float float8 = Float.NaN;
            VehicleInterpolationData vehicleInterpolationData0 = new VehicleInterpolationData();
            vehicleInterpolationData0.time = long0 - (long)this.interpolation.delay;
            VehicleInterpolationData vehicleInterpolationData1 = (VehicleInterpolationData)this.interpolation.buffer.higher(vehicleInterpolationData0);
            VehicleInterpolationData vehicleInterpolationData2 = (VehicleInterpolationData)this.interpolation.buffer.floor(vehicleInterpolationData0);

            for (VehicleInterpolationData vehicleInterpolationData3 : this.interpolation.buffer) {
                boolean boolean0 = (vehicleInterpolationData3.hashCode() & 1) == 0;
                this.renderInterpolateBuffer_drawVertLine(vehicleInterpolationData3.time, color3, float2, float3, float4, float5, long1, long2, boolean0);
                if (vehicleInterpolationData3 == vehicleInterpolationData1) {
                    this.renderInterpolateBuffer_drawTextHL(vehicleInterpolationData3.time, "H", color2, float2, float3, float4, float5, long1, long2);
                }

                if (vehicleInterpolationData3 == vehicleInterpolationData2) {
                    this.renderInterpolateBuffer_drawTextHL(vehicleInterpolationData3.time, "L", color2, float2, float3, float4, float5, long1, long2);
                }

                this.renderInterpolateBuffer_drawPoint(
                    vehicleInterpolationData3.time,
                    vehicleInterpolationData3.x,
                    color4,
                    5,
                    float2,
                    float3,
                    float4,
                    float5,
                    long1,
                    long2,
                    this.x - float6,
                    this.x + float6
                );
                this.renderInterpolateBuffer_drawPoint(
                    vehicleInterpolationData3.time,
                    vehicleInterpolationData3.y,
                    color5,
                    5,
                    float2,
                    float3,
                    float4,
                    float5,
                    long1,
                    long2,
                    this.y - float6,
                    this.y + float6
                );
                if (!Float.isNaN(float7)) {
                    this.renderInterpolateBuffer_drawLine(
                        long3,
                        float7,
                        vehicleInterpolationData3.time,
                        vehicleInterpolationData3.x,
                        color4,
                        float2,
                        float3,
                        float4,
                        float5,
                        long1,
                        long2,
                        this.x - float6,
                        this.x + float6
                    );
                    this.renderInterpolateBuffer_drawLine(
                        long3,
                        float8,
                        vehicleInterpolationData3.time,
                        vehicleInterpolationData3.y,
                        color5,
                        float2,
                        float3,
                        float4,
                        float5,
                        long1,
                        long2,
                        this.y - float6,
                        this.y + float6
                    );
                }

                long3 = vehicleInterpolationData3.time;
                float7 = vehicleInterpolationData3.x;
                float8 = vehicleInterpolationData3.y;
            }

            float[] float9 = new float[27];
            float[] float10 = new float[2];
            boolean boolean1 = this.interpolation.interpolationDataGet(float9, float10, long0 - (long)this.interpolation.delay);
            TextManager.instance
                .DrawString(
                    (double)float2,
                    (double)(float3 + float5 + 20.0F),
                    String.format("interpolationDataGet=%s", boolean1 ? "True" : "False"),
                    (double)color2.r,
                    (double)color2.g,
                    (double)color2.b,
                    (double)color2.a
                );
            TextManager.instance
                .DrawString(
                    (double)float2,
                    (double)(float3 + float5 + 30.0F),
                    String.format("buffer.size=%d buffering=%s", this.interpolation.buffer.size(), String.valueOf(this.interpolation.buffering)),
                    (double)color2.r,
                    (double)color2.g,
                    (double)color2.b,
                    (double)color2.a
                );
            if (this.interpolation.buffer.size() >= 2) {
                TextManager.instance
                    .DrawString(
                        (double)float2,
                        (double)(float3 + float5 + 40.0F),
                        String.format(
                            "last=%d first=%d",
                            ((VehicleInterpolationData)this.interpolation.buffer.last()).time,
                            ((VehicleInterpolationData)this.interpolation.buffer.first()).time
                        ),
                        (double)color2.r,
                        (double)color2.g,
                        (double)color2.b,
                        (double)color2.a
                    );
                TextManager.instance
                    .DrawString(
                        (double)float2,
                        (double)(float3 + float5 + 50.0F),
                        String.format(
                            "(last-first).time=%d delay=%d",
                            ((VehicleInterpolationData)this.interpolation.buffer.last()).time
                                - ((VehicleInterpolationData)this.interpolation.buffer.first()).time,
                            this.interpolation.delay
                        ),
                        (double)color2.r,
                        (double)color2.g,
                        (double)color2.b,
                        (double)color2.a
                    );
            }
        }
    }

    private void renderInterpolateBuffer_drawTextHL(
        long long2, String string, Color color, float float4, float float3, float float1, float var8, long long1, long long0
    ) {
        float float0 = float1 / (float)(long0 - long1);
        float float2 = (float)(long2 - long1) * float0;
        TextManager.instance.DrawString((double)(float2 + float4), (double)float3, string, (double)color.r, (double)color.g, (double)color.b, (double)color.a);
    }

    private void renderInterpolateBuffer_drawVertLine(
        long long2, Color color, float float5, float float3, float float1, float float4, long long1, long long0, boolean _boolean
    ) {
        float float0 = float1 / (float)(long0 - long1);
        float float2 = (float)(long2 - long1) * float0;
        LineDrawer.drawLine(float2 + float5, float3, float2 + float5, float3 + float4, color.r, color.g, color.b, color.a, 1);
        TextManager.instance
            .DrawString(
                (double)(float2 + float5),
                (double)(float3 + float4 + (_boolean ? 0.0F : 10.0F)),
                String.format("%.1f", (float)(long2 - long2 / 100000L * 100000L) / 1000.0F),
                (double)color.r,
                (double)color.g,
                (double)color.b,
                (double)color.a
            );
    }

    private void renderInterpolateBuffer_drawLine(
        long long2,
        float float9,
        long long3,
        float float11,
        Color color,
        float float13,
        float float12,
        float float1,
        float float5,
        long long1,
        long long0,
        float float7,
        float float6
    ) {
        float float0 = float1 / (float)(long0 - long1);
        float float2 = (float)(long2 - long1) * float0;
        float float3 = (float)(long3 - long1) * float0;
        float float4 = float5 / (float6 - float7);
        float float8 = (float9 - float7) * float4;
        float float10 = (float11 - float7) * float4;
        LineDrawer.drawLine(float2 + float13, float8 + float12, float3 + float13, float10 + float12, color.r, color.g, color.b, color.a, 1);
    }

    private void renderInterpolateBuffer_drawPoint(
        long long2,
        float float8,
        Color color,
        int _int,
        float float10,
        float float9,
        float float1,
        float float4,
        long long1,
        long long0,
        float float6,
        float float5
    ) {
        float float0 = float1 / (float)(long0 - long1);
        float float2 = (float)(long2 - long1) * float0;
        float float3 = float4 / (float5 - float6);
        float float7 = (float8 - float6) * float3;
        LineDrawer.drawCircle(float2 + float10, float7 + float9, (float)_int, 10, color.r, color.g, color.b);
    }

    private void renderAuthorizations() {
        float float0 = 0.3F;
        float float1 = 0.3F;
        float float2 = 0.3F;
        float float3 = 0.5F;
        switch (this.netPlayerAuthorization) {
            case Server:
                float0 = 1.0F;
                break;
            case LocalCollide:
                float2 = 1.0F;
                break;
            case Local:
                float1 = 1.0F;
                break;
            case Remote:
                float1 = 1.0F;
                float0 = 1.0F;
                break;
            case RemoteCollide:
                float2 = 1.0F;
                float0 = 1.0F;
        }

        LineDrawer.drawLine(
            IsoUtils.XToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
            IsoUtils.XToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
            float0,
            float1,
            float2,
            float3,
            1
        );
        LineDrawer.drawLine(
            IsoUtils.XToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x2, this.poly.y2, 0.0F, 0),
            IsoUtils.XToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
            float0,
            float1,
            float2,
            float3,
            1
        );
        LineDrawer.drawLine(
            IsoUtils.XToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x3, this.poly.y3, 0.0F, 0),
            IsoUtils.XToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
            float0,
            float1,
            float2,
            float3,
            1
        );
        LineDrawer.drawLine(
            IsoUtils.XToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x4, this.poly.y4, 0.0F, 0),
            IsoUtils.XToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
            IsoUtils.YToScreenExact(this.poly.x1, this.poly.y1, 0.0F, 0),
            float0,
            float1,
            float2,
            float3,
            1
        );
        float float4 = 0.0F;
        if (this.getVehicleTowing() != null) {
            BaseVehicle.Vector3fObjectPool vector3fObjectPool = (BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get();
            Vector3f vector3f0 = vector3fObjectPool.alloc();
            Vector3f vector3f1 = this.getTowingWorldPos(this.getTowAttachmentSelf(), vector3f0);
            Vector3f vector3f2 = vector3fObjectPool.alloc();
            Vector3f vector3f3 = this.getVehicleTowing().getTowingWorldPos(this.getVehicleTowing().getTowAttachmentSelf(), vector3f2);
            if (vector3f1 != null && vector3f3 != null) {
                LineDrawer.DrawIsoLine(vector3f1.x, vector3f1.y, vector3f1.z, vector3f3.x, vector3f3.y, vector3f3.z, float0, float1, float2, float3, 1);
                LineDrawer.DrawIsoCircle(vector3f1.x, vector3f1.y, vector3f1.z, 0.2F, 16, float0, float1, float2, float3);
                float4 = IsoUtils.DistanceTo(vector3f1.x, vector3f1.y, vector3f1.z, vector3f3.x, vector3f3.y, vector3f3.z);
            }

            vector3fObjectPool.release(vector3f0);
            vector3fObjectPool.release(vector3f2);
        }

        float0 = 1.0F;
        float1 = 1.0F;
        float2 = 0.75F;
        float3 = 1.0F;
        float float5 = 10.0F;
        float float6 = IsoUtils.XToScreenExact(this.x, this.y, 0.0F, 0);
        float float7 = IsoUtils.YToScreenExact(this.x, this.y, 0.0F, 0);
        IsoPlayer isoPlayer = (IsoPlayer)GameClient.IDToPlayerMap.get(this.netPlayerId);
        String string = (isoPlayer == null ? "@server" : isoPlayer.getUsername()) + " ( " + this.netPlayerId + " )";
        float float8;
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float8 = float5 + 12.0F)),
                "VID: " + this.getScriptName() + " ( " + this.getId() + " )",
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        TextManager.instance
            .DrawString(
                (double)float6, (double)(float7 + (float5 = float8 + 12.0F)), "PID: " + string, (double)float0, (double)float1, (double)float2, (double)float3
            );
        float float9;
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float9 = float5 + 12.0F)),
                "Auth: " + this.netPlayerAuthorization.name(),
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float5 = float9 + 12.0F)),
                "Static/active: " + this.isStatic + "/" + this.isActive,
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        float float10;
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float10 = float5 + 12.0F)),
                "x=" + this.x + " / y=" + this.y,
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float5 = float10 + 14.0F)),
                String.format(
                    "Passengers: %d/%d", Arrays.stream(this.passengers).filter(passenger -> passenger.character != null).count(), this.passengers.length
                ),
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        float float11;
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float11 = float5 + 12.0F)),
                String.format("Speed: %s%.3f kmph", this.getCurrentSpeedKmHour() >= 0.0F ? "+" : "", this.getCurrentSpeedKmHour()),
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float5 = float11 + 12.0F)),
                String.format("Engine speed: %.3f", this.engineSpeed),
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        float float12;
        TextManager.instance
            .DrawString(
                (double)float6,
                (double)(float7 + (float12 = float5 + 12.0F)),
                String.format("Mass: %.3f/%.3f", this.getMass(), this.getFudgedMass()),
                (double)float0,
                (double)float1,
                (double)float2,
                (double)float3
            );
        if (float4 > 1.5F) {
            float1 = 0.75F;
        }

        if (this.getVehicleTowing() != null) {
            TextManager.instance
                .DrawString(
                    (double)float6,
                    (double)(float7 + (float5 = float12 + 14.0F)),
                    "Towing: " + this.getVehicleTowing().getId(),
                    (double)float0,
                    (double)float1,
                    (double)float2,
                    (double)float3
                );
            TextManager.instance
                .DrawString(
                    (double)float6,
                    (double)(float7 + (float12 = float5 + 12.0F)),
                    String.format("Distance: %.3f", float4),
                    (double)float0,
                    (double)float1,
                    (double)float2,
                    (double)float3
                );
        }

        if (this.getVehicleTowedBy() != null) {
            TextManager.instance
                .DrawString(
                    (double)float6,
                    (double)(float7 + (float5 = float12 + 14.0F)),
                    "TowedBy: " + this.getVehicleTowedBy().getId(),
                    (double)float0,
                    (double)float1,
                    (double)float2,
                    (double)float3
                );
            float float13;
            TextManager.instance
                .DrawString(
                    (double)float6,
                    (double)(float7 + (float13 = float5 + 12.0F)),
                    String.format("Distance: %.3f", float4),
                    (double)float0,
                    (double)float1,
                    (double)float2,
                    (double)float3
                );
        }
    }

    private void renderUsableArea() {
        if (this.getScript() != null && UIManager.VisibleAllUI) {
            VehiclePart vehiclePart = this.getUseablePart(IsoPlayer.getInstance());
            if (vehiclePart != null) {
                VehicleScript.Area area = this.getScript().getAreaById(vehiclePart.getArea());
                if (area != null) {
                    Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                    Vector2 vector21 = this.areaPositionWorld(area, vector20);
                    if (vector21 == null) {
                        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                    } else {
                        Vector3f vector3f = this.getForwardVector(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                        float float0 = Core.getInstance().getGoodHighlitedColor().getR();
                        float float1 = Core.getInstance().getGoodHighlitedColor().getG();
                        float float2 = Core.getInstance().getGoodHighlitedColor().getB();
                        this.getController()
                            .drawRect(
                                vector3f,
                                vector21.x - WorldSimulation.instance.offsetX,
                                vector21.y - WorldSimulation.instance.offsetY,
                                area.w,
                                area.h / 2.0F,
                                float0,
                                float1,
                                float2
                            );
                        vector3f.x = vector3f.x * (area.h / this.script.getModelScale());
                        vector3f.z = vector3f.z * (area.h / this.script.getModelScale());
                        if (vehiclePart.getDoor() != null && (vehiclePart.getId().contains("Left") || vehiclePart.getId().contains("Right"))) {
                            if (vehiclePart.getId().contains("Front")) {
                                this.getController()
                                    .drawRect(
                                        vector3f,
                                        vector21.x - WorldSimulation.instance.offsetX + vector3f.x * area.h / 2.0F,
                                        vector21.y - WorldSimulation.instance.offsetY + vector3f.z * area.h / 2.0F,
                                        area.w,
                                        area.h / 8.0F,
                                        float0,
                                        float1,
                                        float2
                                    );
                            } else if (vehiclePart.getId().contains("Rear")) {
                                this.getController()
                                    .drawRect(
                                        vector3f,
                                        vector21.x - WorldSimulation.instance.offsetX - vector3f.x * area.h / 2.0F,
                                        vector21.y - WorldSimulation.instance.offsetY - vector3f.z * area.h / 2.0F,
                                        area.w,
                                        area.h / 8.0F,
                                        float0,
                                        float1,
                                        float2
                                    );
                            }
                        }

                        ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
                    }
                }
            }
        }
    }

    private void renderIntersectedSquares() {
        PolygonalMap2.VehiclePoly vehiclePoly = this.getPoly();
        float float0 = Math.min(vehiclePoly.x1, Math.min(vehiclePoly.x2, Math.min(vehiclePoly.x3, vehiclePoly.x4)));
        float float1 = Math.min(vehiclePoly.y1, Math.min(vehiclePoly.y2, Math.min(vehiclePoly.y3, vehiclePoly.y4)));
        float float2 = Math.max(vehiclePoly.x1, Math.max(vehiclePoly.x2, Math.max(vehiclePoly.x3, vehiclePoly.x4)));
        float float3 = Math.max(vehiclePoly.y1, Math.max(vehiclePoly.y2, Math.max(vehiclePoly.y3, vehiclePoly.y4)));

        for (int int0 = (int)float1; int0 < (int)Math.ceil((double)float3); int0++) {
            for (int int1 = (int)float0; int1 < (int)Math.ceil((double)float2); int1++) {
                if (this.isIntersectingSquare(int1, int0, (int)this.z)) {
                    LineDrawer.addLine(
                        (float)int1,
                        (float)int0,
                        (float)((int)this.z),
                        (float)(int1 + 1),
                        (float)(int0 + 1),
                        (float)((int)this.z),
                        1.0F,
                        1.0F,
                        1.0F,
                        null,
                        false
                    );
                }
            }
        }
    }

    private void renderTrailerPositions() {
        if (this.script != null && this.physics != null) {
            Vector3f vector3f0 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            Vector3f vector3f2 = this.getTowingWorldPos("trailer", vector3f1);
            if (vector3f2 != null) {
                this.physics.drawCircle(vector3f2.x, vector3f2.y, 0.3F, 1.0F, 1.0F, 1.0F, 1.0F);
            }

            Vector3f vector3f3 = this.getPlayerTrailerLocalPos("trailer", false, vector3f0);
            if (vector3f3 != null) {
                this.getWorldPos(vector3f3, vector3f3);
                boolean boolean0 = PolygonalMap2.instance.lineClearCollide(vector3f1.x, vector3f1.y, vector3f3.x, vector3f3.y, (int)this.z, this, false, false);
                this.physics.drawCircle(vector3f3.x, vector3f3.y, 0.3F, 1.0F, boolean0 ? 0.0F : 1.0F, boolean0 ? 0.0F : 1.0F, 1.0F);
                if (boolean0) {
                    LineDrawer.addLine(vector3f3.x, vector3f3.y, 0.0F, vector3f1.x, vector3f1.y, 0.0F, 1.0F, 0.0F, 0.0F, 1.0F);
                }
            }

            vector3f3 = this.getPlayerTrailerLocalPos("trailer", true, vector3f0);
            if (vector3f3 != null) {
                this.getWorldPos(vector3f3, vector3f3);
                boolean boolean1 = PolygonalMap2.instance.lineClearCollide(vector3f1.x, vector3f1.y, vector3f3.x, vector3f3.y, (int)this.z, this, false, false);
                this.physics.drawCircle(vector3f3.x, vector3f3.y, 0.3F, 1.0F, boolean1 ? 0.0F : 1.0F, boolean1 ? 0.0F : 1.0F, 1.0F);
                if (boolean1) {
                    LineDrawer.addLine(vector3f3.x, vector3f3.y, 0.0F, vector3f1.x, vector3f1.y, 0.0F, 1.0F, 0.0F, 0.0F, 1.0F);
                }
            }

            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
        }
    }

    public void getWheelForwardVector(int _int, Vector3f vector3f) {
        BaseVehicle.WheelInfo wheelInfox = this.wheelInfo[_int];
        Matrix4f matrix4f0 = ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).alloc();
        matrix4f0.rotationY(wheelInfox.steering);
        Matrix4f matrix4f1 = this.jniTransform.getMatrix(((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).alloc());
        matrix4f1.setTranslation(0.0F, 0.0F, 0.0F);
        matrix4f0.mul(matrix4f1, matrix4f0);
        ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).release(matrix4f1);
        ((BaseVehicle.Matrix4fObjectPool)TL_matrix4f_pool.get()).release(matrix4f0);
        matrix4f0.getColumn(2, this.tempVector4f);
        vector3f.set(this.tempVector4f.x, 0.0F, this.tempVector4f.z);
    }

    public void tryStartEngine(boolean haveKey) {
        if (this.getDriver() == null || !(this.getDriver() instanceof IsoPlayer) || !((IsoPlayer)this.getDriver()).isBlockMovement()) {
            if (this.engineState == BaseVehicle.engineStateTypes.Idle) {
                if ((!Core.bDebug || !DebugOptions.instance.CheatVehicleStartWithoutKey.getValue())
                    && !zombie.SandboxOptions.instance.VehicleEasyUse.getValue()
                    && !this.isKeysInIgnition()
                    && !haveKey
                    && this.getDriver().getInventory().haveThisKeyId(this.getKeyId()) == null
                    && !this.isHotwired()) {
                    if (GameServer.bServer) {
                        this.getDriver().sendObjectChange("vehicleNoKey");
                    } else {
                        this.getDriver().SayDebug(" [img=media/ui/CarKey_none.png]");
                    }
                } else {
                    this.engineDoStarting();
                }
            }
        }
    }

    public void tryStartEngine() {
        this.tryStartEngine(false);
    }

    public void engineDoIdle() {
        this.engineState = BaseVehicle.engineStateTypes.Idle;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
    }

    public void engineDoStarting() {
        this.engineState = BaseVehicle.engineStateTypes.Starting;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
        this.setKeysInIgnition(true);
    }

    public boolean isStarting() {
        return this.engineState == BaseVehicle.engineStateTypes.Starting
            || this.engineState == BaseVehicle.engineStateTypes.StartingFailed
            || this.engineState == BaseVehicle.engineStateTypes.StartingSuccess
            || this.engineState == BaseVehicle.engineStateTypes.StartingFailedNoPower;
    }

    private String getEngineSound() {
        return this.getScript() != null && this.getScript().getSounds().engine != null ? this.getScript().getSounds().engine : "VehicleEngineDefault";
    }

    private String getEngineStartSound() {
        return this.getScript() != null && this.getScript().getSounds().engineStart != null ? this.getScript().getSounds().engineStart : "VehicleStarted";
    }

    private String getEngineTurnOffSound() {
        return this.getScript() != null && this.getScript().getSounds().engineTurnOff != null ? this.getScript().getSounds().engineTurnOff : "VehicleTurnedOff";
    }

    private String getIgnitionFailSound() {
        return this.getScript() != null && this.getScript().getSounds().ignitionFail != null
            ? this.getScript().getSounds().ignitionFail
            : "VehicleFailingToStart";
    }

    private String getIgnitionFailNoPowerSound() {
        return this.getScript() != null && this.getScript().getSounds().ignitionFailNoPower != null
            ? this.getScript().getSounds().ignitionFailNoPower
            : "VehicleFailingToStartNoPower";
    }

    public void engineDoRetryingStarting() {
        this.getEmitter().stopSoundByName(this.getIgnitionFailSound());
        this.getEmitter().playSoundImpl(this.getIgnitionFailSound(), (IsoObject)null);
        this.engineState = BaseVehicle.engineStateTypes.RetryingStarting;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
    }

    public void engineDoStartingSuccess() {
        this.getEmitter().stopSoundByName(this.getIgnitionFailSound());
        this.engineState = BaseVehicle.engineStateTypes.StartingSuccess;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        if (this.getEngineStartSound().equals(this.getEngineSound())) {
            if (!this.getEmitter().isPlaying(this.combinedEngineSound)) {
                this.combinedEngineSound = this.emitter.playSoundImpl(this.getEngineSound(), (IsoObject)null);
            }
        } else {
            this.getEmitter().playSoundImpl(this.getEngineStartSound(), (IsoObject)null);
        }

        this.transmitEngine();
        this.setKeysInIgnition(true);
    }

    public void engineDoStartingFailed() {
        this.getEmitter().stopSoundByName(this.getIgnitionFailSound());
        this.getEmitter().playSoundImpl(this.getIgnitionFailSound(), (IsoObject)null);
        this.stopEngineSounds();
        this.engineState = BaseVehicle.engineStateTypes.StartingFailed;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
    }

    public void engineDoStartingFailedNoPower() {
        this.getEmitter().stopSoundByName(this.getIgnitionFailNoPowerSound());
        this.getEmitter().playSoundImpl(this.getIgnitionFailNoPowerSound(), (IsoObject)null);
        this.stopEngineSounds();
        this.engineState = BaseVehicle.engineStateTypes.StartingFailedNoPower;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
    }

    public void engineDoRunning() {
        this.setNeedPartsUpdate(true);
        this.engineState = BaseVehicle.engineStateTypes.Running;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
    }

    public void engineDoStalling() {
        this.getEmitter().playSoundImpl("VehicleRunningOutOfGas", (IsoObject)null);
        this.engineState = BaseVehicle.engineStateTypes.Stalling;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.stopEngineSounds();
        this.engineSoundIndex = 0;
        this.transmitEngine();
        if (!Core.getInstance().getOptionLeaveKeyInIgnition()) {
            this.setKeysInIgnition(false);
        }
    }

    public void engineDoShuttingDown() {
        if (!this.getEngineTurnOffSound().equals(this.getEngineSound())) {
            this.getEmitter().playSoundImpl(this.getEngineTurnOffSound(), (IsoObject)null);
        }

        this.stopEngineSounds();
        this.engineSoundIndex = 0;
        this.engineState = BaseVehicle.engineStateTypes.ShutingDown;
        this.engineLastUpdateStateTime = System.currentTimeMillis();
        this.transmitEngine();
        if (!Core.getInstance().getOptionLeaveKeyInIgnition()) {
            this.setKeysInIgnition(false);
        }

        VehiclePart vehiclePart = this.getHeater();
        if (vehiclePart != null) {
            vehiclePart.getModData().rawset("active", false);
        }
    }

    public void shutOff() {
        if (this.getPartById("GasTank").getContainerContentAmount() == 0.0F) {
            this.engineDoStalling();
        } else {
            this.engineDoShuttingDown();
        }
    }

    public void resumeRunningAfterLoad() {
        if (GameClient.bClient) {
            IsoGameCharacter isoGameCharacter = this.getDriver();
            if (isoGameCharacter != null) {
                Boolean _boolean = this.getDriver().getInventory().haveThisKeyId(this.getKeyId()) != null ? Boolean.TRUE : Boolean.FALSE;
                GameClient.instance.sendClientCommandV((IsoPlayer)this.getDriver(), "vehicle", "startEngine", "haveKey", _boolean);
            }
        } else if (this.isEngineWorking()) {
            this.getEmitter();
            this.engineDoStartingSuccess();
        }
    }

    public boolean isEngineStarted() {
        return this.engineState == BaseVehicle.engineStateTypes.Starting
            || this.engineState == BaseVehicle.engineStateTypes.StartingFailed
            || this.engineState == BaseVehicle.engineStateTypes.StartingSuccess
            || this.engineState == BaseVehicle.engineStateTypes.RetryingStarting;
    }

    public boolean isEngineRunning() {
        return this.engineState == BaseVehicle.engineStateTypes.Running;
    }

    public boolean isEngineWorking() {
        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            String string = vehiclePart.getLuaFunction("checkEngine");
            if (string != null && !Boolean.TRUE.equals(this.callLuaBoolean(string, this, vehiclePart))) {
                return false;
            }
        }

        return true;
    }

    public boolean isOperational() {
        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            String string = vehiclePart.getLuaFunction("checkOperate");
            if (string != null && !Boolean.TRUE.equals(this.callLuaBoolean(string, this, vehiclePart))) {
                return false;
            }
        }

        return true;
    }

    public boolean isDriveable() {
        return !this.isEngineWorking() ? false : this.isOperational();
    }

    public BaseSoundEmitter getEmitter() {
        if (this.emitter == null) {
            if (!Core.SoundDisabled && !GameServer.bServer) {
                FMODSoundEmitter fMODSoundEmitter = new FMODSoundEmitter();
                fMODSoundEmitter.parameterUpdater = this;
                this.emitter = fMODSoundEmitter;
            } else {
                this.emitter = new DummySoundEmitter();
            }
        }

        return this.emitter;
    }

    public long playSoundImpl(String file, IsoObject parent) {
        return this.getEmitter().playSoundImpl(file, parent);
    }

    public int stopSound(long channel) {
        return this.getEmitter().stopSound(channel);
    }

    public void playSound(String sound) {
        this.getEmitter().playSound(sound);
    }

    public void updateSounds() {
        if (!GameServer.bServer) {
            if (this.getBatteryCharge() > 0.0F) {
                if (this.lightbarSirenMode.isEnable() && this.soundSirenSignal == -1L) {
                    this.setLightbarSirenMode(this.lightbarSirenMode.get());
                }
            } else if (this.soundSirenSignal != -1L) {
                this.getEmitter().stopSound(this.soundSirenSignal);
                this.soundSirenSignal = -1L;
            }
        }

        IsoPlayer isoPlayer0 = null;
        float float0 = Float.MAX_VALUE;

        for (int int0 = 0; int0 < IsoPlayer.numPlayers; int0++) {
            IsoPlayer isoPlayer1 = IsoPlayer.players[int0];
            if (isoPlayer1 != null && isoPlayer1.getCurrentSquare() != null) {
                float float1 = isoPlayer1.getX();
                float float2 = isoPlayer1.getY();
                float float3 = IsoUtils.DistanceToSquared(float1, float2, this.x, this.y);
                if (isoPlayer1.Traits.HardOfHearing.isSet()) {
                    float3 *= 4.5F;
                }

                if (isoPlayer1.Traits.Deaf.isSet()) {
                    float3 = Float.MAX_VALUE;
                }

                if (float3 < float0) {
                    isoPlayer0 = isoPlayer1;
                    float0 = float3;
                }
            }
        }

        if (isoPlayer0 == null) {
            if (this.emitter != null) {
                this.emitter.setPos(this.x, this.y, this.z);
                if (!this.emitter.isEmpty()) {
                    this.emitter.tick();
                }
            }
        } else {
            if (!GameServer.bServer) {
                float float4 = ClimateManager.getInstance().isRaining() ? ClimateManager.getInstance().getPrecipitationIntensity() : 0.0F;
                if (this.getSquare() != null && this.getSquare().isInARoom()) {
                    float4 = 0.0F;
                }

                if (this.getEmitter().isPlaying("VehicleAmbiance")) {
                    if (float4 == 0.0F) {
                        this.getEmitter().stopOrTriggerSoundByName("VehicleAmbiance");
                    }
                } else if (float4 > 0.0F && float0 < 100.0F) {
                    this.emitter.playAmbientLoopedImpl("VehicleAmbiance");
                }

                float float5 = float0;
                if (float0 > 1200.0F) {
                    this.stopEngineSounds();
                    if (this.emitter != null && !this.emitter.isEmpty()) {
                        this.emitter.setPos(this.x, this.y, this.z);
                        this.emitter.tick();
                    }

                    return;
                }

                for (int int1 = 0; int1 < this.new_EngineSoundId.length; int1++) {
                    if (this.new_EngineSoundId[int1] != 0L) {
                        this.getEmitter().setVolume(this.new_EngineSoundId[int1], 1.0F - float5 / 1200.0F);
                    }
                }
            }

            this.startTime = this.startTime - zombie.GameTime.instance.getMultiplier();
            if (this.getController() != null) {
                if (!GameServer.bServer) {
                    if (this.emitter == null) {
                        if (this.engineState != BaseVehicle.engineStateTypes.Running) {
                            return;
                        }

                        this.getEmitter();
                    }

                    boolean boolean0 = this.isAnyListenerInside();
                    float float6 = Math.abs(this.getCurrentSpeedKmHour());
                    if (this.startTime <= 0.0F
                        && this.engineState == BaseVehicle.engineStateTypes.Running
                        && !this.getEmitter().isPlaying(this.combinedEngineSound)) {
                        this.combinedEngineSound = this.emitter.playSoundImpl(this.getEngineSound(), (IsoObject)null);
                        if (this.getEngineSound().equals(this.getEngineStartSound())) {
                            this.emitter.setTimelinePosition(this.combinedEngineSound, "idle");
                        }
                    }

                    boolean boolean1 = false;
                    if (!GameClient.bClient || this.isLocalPhysicSim()) {
                        for (int int2 = 0; int2 < this.script.getWheelCount(); int2++) {
                            if (this.wheelInfo[int2].skidInfo < 0.15F) {
                                boolean1 = true;
                                break;
                            }
                        }
                    }

                    if (this.getDriver() == null) {
                        boolean1 = false;
                    }

                    if (boolean1 != this.skidding) {
                        if (boolean1) {
                            this.skidSound = this.getEmitter().playSoundImpl("VehicleSkid", (IsoObject)null);
                        } else if (this.skidSound != 0L) {
                            this.emitter.stopSound(this.skidSound);
                            this.skidSound = 0L;
                        }

                        this.skidding = boolean1;
                    }

                    if (this.soundBackMoveSignal != -1L && this.emitter != null) {
                        this.emitter.set3D(this.soundBackMoveSignal, !boolean0);
                    }

                    if (this.soundHorn != -1L && this.emitter != null) {
                        this.emitter.set3D(this.soundHorn, !boolean0);
                    }

                    if (this.soundSirenSignal != -1L && this.emitter != null) {
                        this.emitter.set3D(this.soundSirenSignal, !boolean0);
                    }

                    if (this.emitter != null && (this.engineState != BaseVehicle.engineStateTypes.Idle || !this.emitter.isEmpty())) {
                        this.getFMODParameters().update();
                        this.emitter.setPos(this.x, this.y, this.z);
                        this.emitter.tick();
                    }
                }
            }
        }
    }

    private boolean updatePart(VehiclePart vehiclePart) {
        vehiclePart.updateSignalDevice();
        VehicleLight vehicleLight = vehiclePart.getLight();
        if (vehicleLight != null && vehiclePart.getId().contains("Headlight")) {
            vehiclePart.setLightActive(this.getHeadlightsOn() && vehiclePart.getInventoryItem() != null && this.getBatteryCharge() > 0.0F);
        }

        String string = vehiclePart.getLuaFunction("update");
        if (string == null) {
            return false;
        } else {
            float float0 = (float)zombie.GameTime.getInstance().getWorldAgeHours();
            if (vehiclePart.getLastUpdated() < 0.0F) {
                vehiclePart.setLastUpdated(float0);
            } else if (vehiclePart.getLastUpdated() > float0) {
                vehiclePart.setLastUpdated(float0);
            }

            float float1 = float0 - vehiclePart.getLastUpdated();
            if ((int)(float1 * 60.0F) > 0) {
                vehiclePart.setLastUpdated(float0);
                this.callLuaVoid(string, this, vehiclePart, (double)(float1 * 60.0F));
                return true;
            } else {
                return false;
            }
        }
    }

    public void updateParts() {
        if (!GameClient.bClient) {
            boolean _boolean = false;

            for (int int0 = 0; int0 < this.getPartCount(); int0++) {
                VehiclePart vehiclePart0 = this.getPartByIndex(int0);
                if (this.updatePart(vehiclePart0) && !_boolean) {
                    _boolean = true;
                }

                if (int0 == this.getPartCount() - 1 && _boolean) {
                    this.brakeBetweenUpdatesSpeed = 0.0F;
                }
            }
        } else {
            for (int int1 = 0; int1 < this.getPartCount(); int1++) {
                VehiclePart vehiclePart1 = this.getPartByIndex(int1);
                vehiclePart1.updateSignalDevice();
            }
        }
    }

    public void drainBatteryUpdateHack() {
        boolean _boolean = this.isEngineRunning();
        if (!_boolean) {
            for (int _int = 0; _int < this.parts.size(); _int++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                if (vehiclePart.getDeviceData() != null && vehiclePart.getDeviceData().getIsTurnedOn()) {
                    this.updatePart(vehiclePart);
                } else if (vehiclePart.getLight() != null && vehiclePart.getLight().getActive()) {
                    this.updatePart(vehiclePart);
                }
            }

            if (this.hasLightbar() && (this.lightbarLightsMode.isEnable() || this.lightbarSirenMode.isEnable()) && this.getBattery() != null) {
                this.updatePart(this.getBattery());
            }
        }
    }

    public boolean getHeadlightsOn() {
        return this.headlightsOn;
    }

    public void setHeadlightsOn(boolean on) {
        if (this.headlightsOn != on) {
            this.headlightsOn = on;
            if (GameServer.bServer) {
                this.updateFlags = (short)(this.updateFlags | 8);
            } else {
                this.playSound(this.headlightsOn ? "VehicleHeadlightsOn" : "VehicleHeadlightsOff");
            }
        }
    }

    public boolean getWindowLightsOn() {
        return this.windowLightsOn;
    }

    public void setWindowLightsOn(boolean on) {
        this.windowLightsOn = on;
    }

    public boolean getHeadlightCanEmmitLight() {
        if (this.getBatteryCharge() <= 0.0F) {
            return false;
        } else {
            VehiclePart vehiclePart = this.getPartById("HeadlightLeft");
            if (vehiclePart != null && vehiclePart.getInventoryItem() != null) {
                return true;
            } else {
                vehiclePart = this.getPartById("HeadlightRight");
                return vehiclePart != null && vehiclePart.getInventoryItem() != null;
            }
        }
    }

    public boolean getStoplightsOn() {
        return this.stoplightsOn;
    }

    public void setStoplightsOn(boolean on) {
        if (this.stoplightsOn != on) {
            this.stoplightsOn = on;
            if (GameServer.bServer) {
                this.updateFlags = (short)(this.updateFlags | 8);
            }
        }
    }

    public boolean hasHeadlights() {
        return this.getLightCount() > 0;
    }

    @Override
    public void addToWorld() {
        if (this.addedToWorld) {
            DebugLog.General.error("added vehicle twice " + this + " id=" + this.VehicleID);
        } else {
            VehiclesDB2.instance.setVehicleLoaded(this);
            this.addedToWorld = true;
            this.removedFromWorld = false;
            super.addToWorld();
            this.createPhysics();

            for (int _int = 0; _int < this.parts.size(); _int++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                if (vehiclePart.getItemContainer() != null) {
                    vehiclePart.getItemContainer().addItemsToProcessItems();
                }

                if (vehiclePart.getDeviceData() != null && !GameServer.bServer) {
                    ZomboidRadio.getInstance().RegisterDevice(vehiclePart);
                }
            }

            if (this.lightbarSirenMode.isEnable()) {
                this.setLightbarSirenMode(this.lightbarSirenMode.get());
                if (this.sirenStartTime <= 0.0) {
                    this.sirenStartTime = zombie.GameTime.instance.getWorldAgeHours();
                }
            }

            if (this.chunk != null && this.chunk.jobType != IsoChunk.JobType.SoftReset) {
                PolygonalMap2.instance.addVehicleToWorld(this);
            }

            if (this.engineState != BaseVehicle.engineStateTypes.Idle) {
                this.engineSpeed = this.getScript() == null ? 1000.0 : (double)this.getScript().getEngineIdleSpeed();
            }

            if (this.chunk != null && this.chunk.jobType != IsoChunk.JobType.SoftReset) {
                this.trySpawnKey();
            }

            if (this.emitter != null) {
                zombie.SoundManager.instance.registerEmitter(this.emitter);
            }
        }
    }

    @Override
    public void removeFromWorld() {
        this.breakConstraint(false, false);
        VehiclesDB2.instance.setVehicleUnloaded(this);

        for (int int0 = 0; int0 < this.passengers.length; int0++) {
            if (this.getPassenger(int0).character != null) {
                for (int int1 = 0; int1 < 4; int1++) {
                    if (this.getPassenger(int0).character == IsoPlayer.players[int1]) {
                        return;
                    }
                }
            }
        }

        IsoChunk.removeFromCheckedVehicles(this);
        DebugLog.Vehicle.trace("BaseVehicle.removeFromWorld() %s id=%d", this, this.VehicleID);
        if (!this.removedFromWorld) {
            if (!this.addedToWorld) {
                DebugLog.Vehicle.debugln("ERROR: removing vehicle but addedToWorld=false %s id=%d", this, this.VehicleID);
            }

            this.removedFromWorld = true;
            this.addedToWorld = false;

            for (int int2 = 0; int2 < this.parts.size(); int2++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(int2);
                if (vehiclePart.getItemContainer() != null) {
                    vehiclePart.getItemContainer().removeItemsFromProcessItems();
                }

                if (vehiclePart.getDeviceData() != null && !GameServer.bServer) {
                    ZomboidRadio.getInstance().UnRegisterDevice(vehiclePart);
                }
            }

            if (this.emitter != null) {
                this.emitter.stopAll();
                zombie.SoundManager.instance.unregisterEmitter(this.emitter);
                this.emitter = null;
            }

            if (this.hornemitter != null && this.soundHorn != -1L) {
                this.hornemitter.stopAll();
                this.soundHorn = -1L;
            }

            if (this.createdModel) {
                ModelManager.instance.Remove(this);
                this.createdModel = false;
            }

            this.releaseAnimationPlayers();
            if (this.getController() != null) {
                if (!GameServer.bServer) {
                    Bullet.removeVehicle(this.VehicleID);
                }

                this.physics = null;
            }

            if (GameServer.bServer || GameClient.bClient) {
                VehicleManager.instance.removeFromWorld(this);
            } else if (this.VehicleID != -1) {
                VehicleIDMap.instance.remove(this.VehicleID);
            }

            IsoWorld.instance.CurrentCell.addVehicles.remove(this);
            IsoWorld.instance.CurrentCell.vehicles.remove(this);
            PolygonalMap2.instance.removeVehicleFromWorld(this);
            if (GameClient.bClient) {
                this.chunk.vehicles.remove(this);
            }

            this.m_surroundVehicle.reset();
            this.removeWorldLights();
            super.removeFromWorld();
        }
    }

    public void permanentlyRemove() {
        for (int _int = 0; _int < this.getMaxPassengers(); _int++) {
            IsoGameCharacter isoGameCharacter = this.getCharacter(_int);
            if (isoGameCharacter != null) {
                if (GameServer.bServer) {
                    isoGameCharacter.sendObjectChange("exitVehicle");
                }

                this.exit(isoGameCharacter);
            }
        }

        this.breakConstraint(true, false);
        this.removeFromWorld();
        this.removeFromSquare();
        if (this.chunk != null) {
            this.chunk.vehicles.remove(this);
        }

        VehiclesDB2.instance.removeVehicle(this);
    }

    public VehiclePart getBattery() {
        return this.battery;
    }

    public void setEngineFeature(int quality, int loudness, int engineForce) {
        this.engineQuality = PZMath.clamp(quality, 0, 100);
        this.engineLoudness = (int)((float)loudness / 2.7F);
        this.enginePower = engineForce;
    }

    public int getEngineQuality() {
        return this.engineQuality;
    }

    public int getEngineLoudness() {
        return this.engineLoudness;
    }

    public int getEnginePower() {
        return this.enginePower;
    }

    public float getBatteryCharge() {
        VehiclePart vehiclePart = this.getBattery();
        return vehiclePart != null && vehiclePart.getInventoryItem() instanceof DrainableComboItem
            ? ((DrainableComboItem)vehiclePart.getInventoryItem()).getUsedDelta()
            : 0.0F;
    }

    public int getPartCount() {
        return this.parts.size();
    }

    public VehiclePart getPartByIndex(int index) {
        return index >= 0 && index < this.parts.size() ? (VehiclePart)this.parts.get(index) : null;
    }

    public VehiclePart getPartById(String id) {
        if (id == null) {
            return null;
        } else {
            for (int _int = 0; _int < this.parts.size(); _int++) {
                VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
                VehicleScript.Part part = vehiclePart.getScriptPart();
                if (part != null && id.equals(part.id)) {
                    return vehiclePart;
                }
            }

            return null;
        }
    }

    public int getNumberOfPartsWithContainers() {
        if (this.getScript() == null) {
            return 0;
        } else {
            int int0 = 0;

            for (int int1 = 0; int1 < this.getScript().getPartCount(); int1++) {
                if (this.getScript().getPart(int1).container != null) {
                    int0++;
                }
            }

            return int0;
        }
    }

    public VehiclePart getPartForSeatContainer(int seat) {
        if (this.getScript() != null && seat >= 0 && seat < this.getMaxPassengers()) {
            for (int _int = 0; _int < this.getPartCount(); _int++) {
                VehiclePart vehiclePart = this.getPartByIndex(_int);
                if (vehiclePart.getContainerSeatNumber() == seat) {
                    return vehiclePart;
                }
            }

            return null;
        } else {
            return null;
        }
    }

    public void transmitPartCondition(VehiclePart part) {
        if (GameServer.bServer) {
            if (this.parts.contains(part)) {
                part.updateFlags = (short)(part.updateFlags | 2048);
                this.updateFlags = (short)(this.updateFlags | 2048);
            }
        }
    }

    public void transmitPartItem(VehiclePart part) {
        if (GameServer.bServer) {
            if (this.parts.contains(part)) {
                part.updateFlags = (short)(part.updateFlags | 128);
                this.updateFlags = (short)(this.updateFlags | 128);
            }
        }
    }

    public void transmitPartModData(VehiclePart part) {
        if (GameServer.bServer) {
            if (this.parts.contains(part)) {
                part.updateFlags = (short)(part.updateFlags | 16);
                this.updateFlags = (short)(this.updateFlags | 16);
            }
        }
    }

    public void transmitPartUsedDelta(VehiclePart part) {
        if (GameServer.bServer) {
            if (this.parts.contains(part)) {
                if (part.getInventoryItem() instanceof DrainableComboItem) {
                    part.updateFlags = (short)(part.updateFlags | 32);
                    this.updateFlags = (short)(this.updateFlags | 32);
                }
            }
        }
    }

    public void transmitPartDoor(VehiclePart part) {
        if (GameServer.bServer) {
            if (this.parts.contains(part)) {
                if (part.getDoor() != null) {
                    part.updateFlags = (short)(part.updateFlags | 512);
                    this.updateFlags = (short)(this.updateFlags | 512);
                }
            }
        }
    }

    public void transmitPartWindow(VehiclePart part) {
        if (GameServer.bServer) {
            if (this.parts.contains(part)) {
                if (part.getWindow() != null) {
                    part.updateFlags = (short)(part.updateFlags | 256);
                    this.updateFlags = (short)(this.updateFlags | 256);
                }
            }
        }
    }

    public int getLightCount() {
        return this.lights.size();
    }

    public VehiclePart getLightByIndex(int index) {
        return index >= 0 && index < this.lights.size() ? (VehiclePart)this.lights.get(index) : null;
    }

    public String getZone() {
        return this.respawnZone;
    }

    public void setZone(String name) {
        this.respawnZone = name;
    }

    public boolean isInArea(String areaId, IsoGameCharacter chr) {
        if (areaId != null && this.getScript() != null) {
            VehicleScript.Area area = this.getScript().getAreaById(areaId);
            if (area == null) {
                return false;
            } else {
                Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).alloc();
                Vector2 vector21 = this.areaPositionLocal(area, vector20);
                if (vector21 == null) {
                    ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                    return false;
                } else {
                    Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
                    this.getLocalPos(chr.x, chr.y, this.z, vector3f);
                    float float0 = vector21.x - area.w / 2.0F;
                    float float1 = vector21.y - area.h / 2.0F;
                    float float2 = vector21.x + area.w / 2.0F;
                    float float3 = vector21.y + area.h / 2.0F;
                    ((BaseVehicle.Vector2ObjectPool)TL_vector2_pool.get()).release(vector20);
                    boolean _boolean = vector3f.x >= float0 && vector3f.x < float2 && vector3f.z >= float1 && vector3f.z < float3;
                    ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
                    return _boolean;
                }
            }
        } else {
            return false;
        }
    }

    public float getAreaDist(String areaId, IsoGameCharacter chr) {
        if (areaId != null && this.getScript() != null) {
            VehicleScript.Area area = this.getScript().getAreaById(areaId);
            if (area != null) {
                Vector3f vector3f = this.getLocalPos(chr.x, chr.y, this.z, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
                float float0 = Math.abs(area.x - area.w / 2.0F);
                float float1 = Math.abs(area.y - area.h / 2.0F);
                float float2 = Math.abs(area.x + area.w / 2.0F);
                float float3 = Math.abs(area.y + area.h / 2.0F);
                float float4 = Math.abs(vector3f.x + float0) + Math.abs(vector3f.z + float1);
                ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
                return float4;
            } else {
                return 999.0F;
            }
        } else {
            return 999.0F;
        }
    }

    public Vector2 getAreaCenter(String areaId) {
        return this.getAreaCenter(areaId, new Vector2());
    }

    public Vector2 getAreaCenter(String areaId, Vector2 out) {
        if (areaId != null && this.getScript() != null) {
            VehicleScript.Area area = this.getScript().getAreaById(areaId);
            return area == null ? null : this.areaPositionWorld(area, out);
        } else {
            return null;
        }
    }

    public boolean isInBounds(float worldX, float worldY) {
        return this.getPoly().containsPoint(worldX, worldY);
    }

    public boolean canAccessContainer(int partIndex, IsoGameCharacter chr) {
        VehiclePart vehiclePart = this.getPartByIndex(partIndex);
        if (vehiclePart == null) {
            return false;
        } else {
            VehicleScript.Part part = vehiclePart.getScriptPart();
            if (part == null) {
                return false;
            } else if (part.container == null) {
                return false;
            } else if (vehiclePart.isInventoryItemUninstalled() && part.container.capacity == 0) {
                return false;
            } else {
                return part.container.luaTest != null && !part.container.luaTest.isEmpty()
                    ? Boolean.TRUE.equals(this.callLuaBoolean(part.container.luaTest, this, vehiclePart, chr))
                    : true;
            }
        }
    }

    public boolean canInstallPart(IsoGameCharacter chr, VehiclePart part) {
        if (!this.parts.contains(part)) {
            return false;
        } else {
            KahluaTable kahluaTable = part.getTable("install");
            return kahluaTable != null && kahluaTable.rawget("test") instanceof String
                ? Boolean.TRUE.equals(this.callLuaBoolean((String)kahluaTable.rawget("test"), this, part, chr))
                : false;
        }
    }

    public boolean canUninstallPart(IsoGameCharacter chr, VehiclePart part) {
        if (!this.parts.contains(part)) {
            return false;
        } else {
            KahluaTable kahluaTable = part.getTable("uninstall");
            return kahluaTable != null && kahluaTable.rawget("test") instanceof String
                ? Boolean.TRUE.equals(this.callLuaBoolean((String)kahluaTable.rawget("test"), this, part, chr))
                : false;
        }
    }

    private void callLuaVoid(String string, Object object1, Object object2) {
        Object object0 = LuaManager.getFunctionObject(string);
        if (object0 != null) {
            LuaManager.caller.protectedCallVoid(LuaManager.thread, object0, object1, object2);
        }
    }

    private void callLuaVoid(String string, Object object1, Object object2, Object object3) {
        Object object0 = LuaManager.getFunctionObject(string);
        if (object0 != null) {
            LuaManager.caller.protectedCallVoid(LuaManager.thread, object0, object1, object2, object3);
        }
    }

    private Boolean callLuaBoolean(String string, Object object1, Object object2) {
        Object object0 = LuaManager.getFunctionObject(string);
        return object0 == null ? null : LuaManager.caller.protectedCallBoolean(LuaManager.thread, object0, object1, object2);
    }

    private Boolean callLuaBoolean(String string, Object object1, Object object2, Object object3) {
        Object object0 = LuaManager.getFunctionObject(string);
        return object0 == null ? null : LuaManager.caller.protectedCallBoolean(LuaManager.thread, object0, object1, object2, object3);
    }

    public short getId() {
        return this.VehicleID;
    }

    public void setTireInflation(int wheelIndex, float inflation) {
    }

    public void setTireRemoved(int wheelIndex, boolean removed) {
        if (!GameServer.bServer) {
            Bullet.setTireRemoved(this.VehicleID, wheelIndex, removed);
        }
    }

    public Vector3f chooseBestAttackPosition(IsoGameCharacter isoGameCharacter1, IsoGameCharacter isoGameCharacter0, Vector3f vector3f) {
        Vector2f vector2f0 = ((BaseVehicle.Vector2fObjectPool)TL_vector2f_pool.get()).alloc();
        Vector2f vector2f1 = isoGameCharacter1.getVehicle().getSurroundVehicle().getPositionForZombie((IsoZombie)isoGameCharacter0, vector2f0);
        float float0 = vector2f0.x;
        float float1 = vector2f0.y;
        ((BaseVehicle.Vector2fObjectPool)TL_vector2f_pool.get()).release(vector2f0);
        return vector2f1 != null ? vector3f.set(float0, float1, this.z) : null;
    }

    public BaseVehicle.MinMaxPosition getMinMaxPosition() {
        BaseVehicle.MinMaxPosition minMaxPosition = new BaseVehicle.MinMaxPosition();
        float float0 = this.getX();
        float float1 = this.getY();
        Vector3f vector3f = this.getScript().getExtents();
        float float2 = vector3f.x;
        float float3 = vector3f.z;
        IsoDirections isoDirections = this.getDir();
        switch (isoDirections) {
            case E:
            case W:
                minMaxPosition.minX = float0 - float2 / 2.0F;
                minMaxPosition.maxX = float0 + float2 / 2.0F;
                minMaxPosition.minY = float1 - float3 / 2.0F;
                minMaxPosition.maxY = float1 + float3 / 2.0F;
                break;
            case N:
            case S:
                minMaxPosition.minX = float0 - float3 / 2.0F;
                minMaxPosition.maxX = float0 + float3 / 2.0F;
                minMaxPosition.minY = float1 - float2 / 2.0F;
                minMaxPosition.maxY = float1 + float2 / 2.0F;
                break;
            default:
                return null;
        }

        return minMaxPosition;
    }

    public String getVehicleType() {
        return this.type;
    }

    public void setVehicleType(String _type) {
        this.type = _type;
    }

    public float getMaxSpeed() {
        return this.maxSpeed;
    }

    public void setMaxSpeed(float _maxSpeed) {
        this.maxSpeed = _maxSpeed;
    }

    public void lockServerUpdate(long lockTimeMs) {
        this.updateLockTimeout = System.currentTimeMillis() + lockTimeMs;
    }

    public void changeTransmission(TransmissionNumber newTransmission) {
        this.transmissionNumber = newTransmission;
    }

    public void tryHotwire(int electricityLevel) {
        int int0 = Math.max(100 - this.getEngineQuality(), 5);
        int0 = Math.min(int0, 50);
        int int1 = electricityLevel * 4;
        int int2 = int0 + int1;
        boolean _boolean = false;
        Object object = null;
        if (Rand.Next(100) <= 11 - electricityLevel && this.alarmed) {
            this.triggerAlarm();
        }

        if (Rand.Next(100) <= int2) {
            this.setHotwired(true);
            _boolean = true;
            object = "VehicleHotwireSuccess";
        } else if (Rand.Next(100) <= 10 - electricityLevel) {
            this.setHotwiredBroken(true);
            _boolean = true;
            object = "VehicleHotwireFail";
        } else {
            object = "VehicleHotwireFail";
        }

        if (object != null) {
            if (GameServer.bServer) {
                LuaManager.GlobalObject.playServerSound((String)object, this.square);
            } else if (this.getDriver() != null) {
                this.getDriver().getEmitter().playSound((String)object);
            }
        }

        if (_boolean && GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 4096);
        }
    }

    public void cheatHotwire(boolean _hotwired, boolean broken) {
        if (_hotwired != this.hotwired || broken != this.hotwiredBroken) {
            this.hotwired = _hotwired;
            this.hotwiredBroken = broken;
            if (GameServer.bServer) {
                this.updateFlags = (short)(this.updateFlags | 4096);
            }
        }
    }

    public boolean isKeyIsOnDoor() {
        return this.keyIsOnDoor;
    }

    public void setKeyIsOnDoor(boolean _keyIsOnDoor) {
        this.keyIsOnDoor = _keyIsOnDoor;
    }

    public boolean isHotwired() {
        return this.hotwired;
    }

    public void setHotwired(boolean _hotwired) {
        this.hotwired = _hotwired;
    }

    public boolean isHotwiredBroken() {
        return this.hotwiredBroken;
    }

    public void setHotwiredBroken(boolean _hotwiredBroken) {
        this.hotwiredBroken = _hotwiredBroken;
    }

    public IsoGameCharacter getDriver() {
        BaseVehicle.Passenger passenger = this.getPassenger(0);
        return passenger == null ? null : passenger.character;
    }

    public boolean isKeysInIgnition() {
        return this.keysInIgnition;
    }

    public void setKeysInIgnition(boolean keysOnContact) {
        IsoGameCharacter isoGameCharacter = this.getDriver();
        if (isoGameCharacter != null) {
            this.setAlarmed(false);
            if (!GameClient.bClient || isoGameCharacter instanceof IsoPlayer && ((IsoPlayer)isoGameCharacter).isLocalPlayer()) {
                if (!this.isHotwired()) {
                    if (!GameServer.bServer && keysOnContact && !this.keysInIgnition) {
                        InventoryItem inventoryItem0 = this.getDriver().getInventory().haveThisKeyId(this.getKeyId());
                        if (inventoryItem0 != null) {
                            this.setCurrentKey(inventoryItem0);
                            InventoryItem inventoryItem1 = inventoryItem0.getContainer().getContainingItem();
                            if (inventoryItem1 instanceof InventoryContainer && "KeyRing".equals(inventoryItem1.getType())) {
                                inventoryItem0.getModData().rawset("keyRing", (double)inventoryItem1.getID());
                            } else if (inventoryItem0.hasModData()) {
                                inventoryItem0.getModData().rawset("keyRing", null);
                            }

                            inventoryItem0.getContainer().DoRemoveItem(inventoryItem0);
                            this.keysInIgnition = keysOnContact;
                            if (GameClient.bClient) {
                                GameClient.instance.sendClientCommandV((IsoPlayer)this.getDriver(), "vehicle", "putKeyInIgnition", "key", inventoryItem0);
                            }
                        }
                    }

                    if (!keysOnContact && this.keysInIgnition && !GameServer.bServer) {
                        if (this.currentKey == null) {
                            this.currentKey = this.createVehicleKey();
                        }

                        InventoryItem inventoryItem2 = this.getCurrentKey();
                        ItemContainer itemContainer = this.getDriver().getInventory();
                        if (inventoryItem2.hasModData() && inventoryItem2.getModData().rawget("keyRing") instanceof Double) {
                            Double _double = (Double)inventoryItem2.getModData().rawget("keyRing");
                            InventoryItem inventoryItem3 = itemContainer.getItemWithID(_double.intValue());
                            if (inventoryItem3 instanceof InventoryContainer && "KeyRing".equals(inventoryItem3.getType())) {
                                itemContainer = ((InventoryContainer)inventoryItem3).getInventory();
                            }

                            inventoryItem2.getModData().rawset("keyRing", null);
                        }

                        itemContainer.addItem(inventoryItem2);
                        this.setCurrentKey(null);
                        this.keysInIgnition = keysOnContact;
                        if (GameClient.bClient) {
                            GameClient.instance.sendClientCommand((IsoPlayer)this.getDriver(), "vehicle", "removeKeyFromIgnition", (KahluaTable)null);
                        }
                    }
                }
            }
        }
    }

    public void putKeyInIgnition(InventoryItem key) {
        if (GameServer.bServer) {
            if (key instanceof Key) {
                if (!this.keysInIgnition) {
                    this.keysInIgnition = true;
                    this.keyIsOnDoor = false;
                    this.currentKey = key;
                    this.updateFlags = (short)(this.updateFlags | 4096);
                }
            }
        }
    }

    public void removeKeyFromIgnition() {
        if (GameServer.bServer) {
            if (this.keysInIgnition) {
                this.keysInIgnition = false;
                this.currentKey = null;
                this.updateFlags = (short)(this.updateFlags | 4096);
            }
        }
    }

    public void putKeyOnDoor(InventoryItem key) {
        if (GameServer.bServer) {
            if (key instanceof Key) {
                if (!this.keyIsOnDoor) {
                    this.keyIsOnDoor = true;
                    this.keysInIgnition = false;
                    this.currentKey = key;
                    this.updateFlags = (short)(this.updateFlags | 4096);
                }
            }
        }
    }

    public void removeKeyFromDoor() {
        if (GameServer.bServer) {
            if (this.keyIsOnDoor) {
                this.keyIsOnDoor = false;
                this.currentKey = null;
                this.updateFlags = (short)(this.updateFlags | 4096);
            }
        }
    }

    public void syncKeyInIgnition(boolean inIgnition, boolean onDoor, InventoryItem key) {
        if (GameClient.bClient) {
            if (!(this.getDriver() instanceof IsoPlayer) || !((IsoPlayer)this.getDriver()).isLocalPlayer()) {
                this.keysInIgnition = inIgnition;
                this.keyIsOnDoor = onDoor;
                this.currentKey = key;
            }
        }
    }

    private void randomizeContainers() {
        if (!GameClient.bClient) {
            boolean _boolean = true;
            String string = this.getScriptName().substring(this.getScriptName().indexOf(46) + 1);
            ItemPickerJava.VehicleDistribution vehicleDistribution = ItemPickerJava.VehicleDistributions.get(string + this.getSkinIndex());
            if (vehicleDistribution != null) {
                _boolean = false;
            } else {
                vehicleDistribution = ItemPickerJava.VehicleDistributions.get(string);
            }

            if (vehicleDistribution == null) {
                for (int int0 = 0; int0 < this.parts.size(); int0++) {
                    VehiclePart vehiclePart0 = (VehiclePart)this.parts.get(int0);
                    if (vehiclePart0.getItemContainer() != null) {
                        if (Core.bDebug) {
                            DebugLog.log("VEHICLE MISSING CONT DISTRIBUTION: " + string);
                        }

                        return;
                    }
                }
            } else {
                ItemPickerJava.ItemPickerRoom itemPickerRoom0;
                if (_boolean && Rand.Next(100) <= 8 && !vehicleDistribution.Specific.isEmpty()) {
                    itemPickerRoom0 = PZArrayUtil.pickRandom(vehicleDistribution.Specific);
                } else {
                    itemPickerRoom0 = vehicleDistribution.Normal;
                }

                if (!StringUtils.isNullOrWhitespace(this.specificDistributionId)) {
                    for (int int1 = 0; int1 < vehicleDistribution.Specific.size(); int1++) {
                        ItemPickerJava.ItemPickerRoom itemPickerRoom1 = (ItemPickerJava.ItemPickerRoom)vehicleDistribution.Specific.get(int1);
                        if (this.specificDistributionId.equals(itemPickerRoom1.specificId)) {
                            itemPickerRoom0 = itemPickerRoom1;
                            break;
                        }
                    }
                }

                for (int int2 = 0; int2 < this.parts.size(); int2++) {
                    VehiclePart vehiclePart1 = (VehiclePart)this.parts.get(int2);
                    if (vehiclePart1.getItemContainer() != null) {
                        if (GameServer.bServer && GameServer.bSoftReset) {
                            vehiclePart1.getItemContainer().setExplored(false);
                        }

                        if (!vehiclePart1.getItemContainer().bExplored) {
                            vehiclePart1.getItemContainer().clear();
                            if (Rand.Next(100) <= 100) {
                                this.randomizeContainer(vehiclePart1, itemPickerRoom0);
                                LuaEventManager.triggerEvent(
                                    "OnFillContainer", string, vehiclePart1.getItemContainer().getType(), vehiclePart1.getItemContainer()
                                );
                            }

                            vehiclePart1.getItemContainer().setExplored(true);
                        }
                    }
                }
            }
        }
    }

    private void randomizeContainer(VehiclePart vehiclePart, ItemPickerJava.ItemPickerRoom itemPickerRoom) {
        if (!GameClient.bClient) {
            if (itemPickerRoom != null) {
                if (!vehiclePart.getId().contains("Seat") && !itemPickerRoom.Containers.containsKey(vehiclePart.getId())) {
                    DebugLog.log("NO CONT DISTRIB FOR PART: " + vehiclePart.getId() + " CAR: " + this.getScriptName().replaceFirst("Base.", ""));
                }

                ItemPickerJava.fillContainerType(itemPickerRoom, vehiclePart.getItemContainer(), "", null);
                if (GameServer.bServer && !vehiclePart.getItemContainer().getItems().isEmpty()) {
                }
            }
        }
    }

    public boolean hasHorn() {
        return this.script.getSounds().hornEnable;
    }

    public boolean hasLightbar() {
        VehiclePart vehiclePart = this.getPartById("lightbar");
        return this.script.getLightbar().enable;
    }

    public void onHornStart() {
        this.soundHornOn = true;
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 1024);
            if (this.script.getSounds().hornEnable) {
                zombie.WorldSoundManager.instance.addSound(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), 150, 150, false);
            }
        } else {
            if (this.soundHorn != -1L) {
                this.hornemitter.stopSound(this.soundHorn);
            }

            if (this.script.getSounds().hornEnable) {
                this.hornemitter = IsoWorld.instance.getFreeEmitter(this.getX(), this.getY(), (float)((int)this.getZ()));
                this.soundHorn = this.hornemitter.playSoundLoopedImpl(this.script.getSounds().horn);
                this.hornemitter.set3D(this.soundHorn, !this.isAnyListenerInside());
                this.hornemitter.setVolume(this.soundHorn, 1.0F);
                this.hornemitter.setPitch(this.soundHorn, 1.0F);
                if (!GameClient.bClient) {
                    zombie.WorldSoundManager.instance.addSound(this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), 150, 150, false);
                }
            }
        }
    }

    public void onHornStop() {
        this.soundHornOn = false;
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 1024);
        } else {
            if (this.script.getSounds().hornEnable && this.soundHorn != -1L) {
                this.hornemitter.stopSound(this.soundHorn);
                this.soundHorn = -1L;
            }
        }
    }

    public boolean hasBackSignal() {
        return this.script != null && this.script.getSounds().backSignalEnable;
    }

    public boolean isBackSignalEmitting() {
        return this.soundBackMoveSignal != -1L;
    }

    public void onBackMoveSignalStart() {
        this.soundBackMoveOn = true;
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 1024);
        } else {
            if (this.soundBackMoveSignal != -1L) {
                this.emitter.stopSound(this.soundBackMoveSignal);
            }

            if (this.script.getSounds().backSignalEnable) {
                this.soundBackMoveSignal = this.emitter.playSoundLoopedImpl(this.script.getSounds().backSignal);
                this.emitter.set3D(this.soundBackMoveSignal, !this.isAnyListenerInside());
            }
        }
    }

    public void onBackMoveSignalStop() {
        this.soundBackMoveOn = false;
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 1024);
        } else {
            if (this.script.getSounds().backSignalEnable && this.soundBackMoveSignal != -1L) {
                this.emitter.stopSound(this.soundBackMoveSignal);
                this.soundBackMoveSignal = -1L;
            }
        }
    }

    public int getLightbarLightsMode() {
        return this.lightbarLightsMode.get();
    }

    public void setLightbarLightsMode(int mode) {
        this.lightbarLightsMode.set(mode);
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 1024);
        }
    }

    public int getLightbarSirenMode() {
        return this.lightbarSirenMode.get();
    }

    public void setLightbarSirenMode(int mode) {
        if (this.soundSirenSignal != -1L) {
            this.getEmitter().stopSound(this.soundSirenSignal);
            this.soundSirenSignal = -1L;
        }

        this.lightbarSirenMode.set(mode);
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 1024);
        } else {
            if (this.lightbarSirenMode.isEnable() && this.getBatteryCharge() > 0.0F) {
                this.soundSirenSignal = this.getEmitter().playSoundLoopedImpl(this.lightbarSirenMode.getSoundName(this.script.getLightbar()));
                this.getEmitter().set3D(this.soundSirenSignal, !this.isAnyListenerInside());
            }
        }
    }

    public HashMap<String, String> getChoosenParts() {
        return this.choosenParts;
    }

    public float getMass() {
        float _float = this.mass;
        if (_float < 0.0F) {
            _float = 1.0F;
        }

        return _float;
    }

    public void setMass(float _mass) {
        this.mass = _mass;
    }

    public float getInitialMass() {
        return this.initialMass;
    }

    public void setInitialMass(float _initialMass) {
        this.initialMass = _initialMass;
    }

    public void updateTotalMass() {
        float _float = 0.0F;

        for (int _int = 0; _int < this.parts.size(); _int++) {
            VehiclePart vehiclePart = (VehiclePart)this.parts.get(_int);
            if (vehiclePart.getItemContainer() != null) {
                _float += vehiclePart.getItemContainer().getCapacityWeight();
            }

            if (vehiclePart.getInventoryItem() != null) {
                _float += vehiclePart.getInventoryItem().getWeight();
            }
        }

        this.setMass((float)Math.round(this.getInitialMass() + _float));
        if (this.physics != null && !GameServer.bServer) {
            Bullet.setVehicleMass(this.VehicleID, this.getMass());
        }
    }

    public float getBrakingForce() {
        return this.brakingForce;
    }

    public void setBrakingForce(float _brakingForce) {
        this.brakingForce = _brakingForce;
    }

    public float getBaseQuality() {
        return this.baseQuality;
    }

    public void setBaseQuality(float _baseQuality) {
        this.baseQuality = _baseQuality;
    }

    public float getCurrentSteering() {
        return this.currentSteering;
    }

    public void setCurrentSteering(float _currentSteering) {
        this.currentSteering = _currentSteering;
    }

    public boolean isDoingOffroad() {
        if (this.getCurrentSquare() == null) {
            return false;
        } else {
            IsoObject isoObject = this.getCurrentSquare().getFloor();
            if (isoObject != null && isoObject.getSprite() != null) {
                String string = isoObject.getSprite().getName();
                return string == null
                    ? false
                    : !string.contains("carpentry_02") && !string.contains("blends_street") && !string.contains("floors_exterior_street");
            } else {
                return false;
            }
        }
    }

    public boolean isBraking() {
        return this.isBraking;
    }

    public void setBraking(boolean _isBraking) {
        this.isBraking = _isBraking;
        if (_isBraking && this.brakeBetweenUpdatesSpeed == 0.0F) {
            this.brakeBetweenUpdatesSpeed = Math.abs(this.getCurrentSpeedKmHour());
        }
    }

    public void updatePartStats() {
        this.setBrakingForce(0.0F);
        this.engineLoudness = (int)((double)this.getScript().getEngineLoudness() * zombie.SandboxOptions.instance.ZombieAttractionMultiplier.getValue() / 2.0);
        boolean _boolean = false;

        for (int _int = 0; _int < this.getPartCount(); _int++) {
            VehiclePart vehiclePart = this.getPartByIndex(_int);
            if (vehiclePart.getInventoryItem() != null) {
                if (vehiclePart.getInventoryItem().getBrakeForce() > 0.0F) {
                    float float0 = VehiclePart.getNumberByCondition(
                        vehiclePart.getInventoryItem().getBrakeForce(), (float)vehiclePart.getInventoryItem().getCondition(), 5.0F
                    );
                    float0 += float0 / 50.0F * (float)vehiclePart.getMechanicSkillInstaller();
                    this.setBrakingForce(this.getBrakingForce() + float0);
                }

                if (vehiclePart.getInventoryItem().getWheelFriction() > 0.0F) {
                    vehiclePart.setWheelFriction(0.0F);
                    float float1 = VehiclePart.getNumberByCondition(
                        vehiclePart.getInventoryItem().getWheelFriction(), (float)vehiclePart.getInventoryItem().getCondition(), 0.2F
                    );
                    float1 += 0.1F * (float)vehiclePart.getMechanicSkillInstaller();
                    float1 = Math.min(2.3F, float1);
                    vehiclePart.setWheelFriction(float1);
                }

                if (vehiclePart.getInventoryItem().getSuspensionCompression() > 0.0F) {
                    vehiclePart.setSuspensionCompression(
                        VehiclePart.getNumberByCondition(
                            vehiclePart.getInventoryItem().getSuspensionCompression(), (float)vehiclePart.getInventoryItem().getCondition(), 0.6F
                        )
                    );
                    vehiclePart.setSuspensionDamping(
                        VehiclePart.getNumberByCondition(
                            vehiclePart.getInventoryItem().getSuspensionDamping(), (float)vehiclePart.getInventoryItem().getCondition(), 0.6F
                        )
                    );
                }

                if (vehiclePart.getInventoryItem().getEngineLoudness() > 0.0F) {
                    vehiclePart.setEngineLoudness(
                        VehiclePart.getNumberByCondition(
                            vehiclePart.getInventoryItem().getEngineLoudness(), (float)vehiclePart.getInventoryItem().getCondition(), 10.0F
                        )
                    );
                    this.engineLoudness = (int)((float)this.engineLoudness * (1.0F + (100.0F - vehiclePart.getEngineLoudness()) / 100.0F));
                    _boolean = true;
                }
            }
        }

        if (!_boolean) {
            this.engineLoudness *= 2;
        }
    }

    public void transmitEngine() {
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 4);
        }
    }

    public void setRust(float _rust) {
        this.rust = PZMath.clamp(_rust, 0.0F, 1.0F);
    }

    public float getRust() {
        return this.rust;
    }

    public void transmitRust() {
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 4096);
        }
    }

    public void transmitColorHSV() {
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 4096);
        }
    }

    public void transmitSkinIndex() {
        if (GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 4096);
        }
    }

    public void updateBulletStats() {
        if (!this.getScriptName().contains("Burnt") && WorldSimulation.instance.created) {
            float[] float0 = wheelParams;
            double double0 = 2.4;
            byte _byte = 5;
            double double1;
            float float1;
            if (this.isInForest() && this.isDoingOffroad() && Math.abs(this.getCurrentSpeedKmHour()) > 1.0F) {
                double1 = (double)Rand.Next(0.08F, 0.18F);
                float1 = 0.7F;
                _byte = 3;
            } else if (this.isDoingOffroad() && Math.abs(this.getCurrentSpeedKmHour()) > 1.0F) {
                double1 = (double)Rand.Next(0.05F, 0.15F);
                float1 = 0.7F;
            } else {
                if (Math.abs(this.getCurrentSpeedKmHour()) > 1.0F && Rand.Next(100) < 10) {
                    double1 = (double)Rand.Next(0.05F, 0.15F);
                } else {
                    double1 = 0.0;
                }

                float1 = 1.0F;
            }

            if (RainManager.isRaining()) {
                float1 -= 0.3F;
            }

            Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();

            for (int _int = 0; _int < this.script.getWheelCount(); _int++) {
                this.updateBulletStatsWheel(_int, float0, vector3f, float1, _byte, double0, double1);
            }

            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            if (zombie.SystemDisabler.getdoVehicleLowRider() && this.isKeyboardControlled()) {
                float float2 = 1.6F;
                float float3 = 1.0F;
                if (GameKeyboard.isKeyDown(79)) {
                    lowRiderParam[0] = lowRiderParam[0] + (float2 - lowRiderParam[0]) * float3;
                } else {
                    lowRiderParam[0] = lowRiderParam[0] + (0.0F - lowRiderParam[0]) * 0.05F;
                }

                if (GameKeyboard.isKeyDown(80)) {
                    lowRiderParam[1] = lowRiderParam[1] + (float2 - lowRiderParam[1]) * float3;
                } else {
                    lowRiderParam[1] = lowRiderParam[1] + (0.0F - lowRiderParam[1]) * 0.05F;
                }

                if (GameKeyboard.isKeyDown(75)) {
                    lowRiderParam[2] = lowRiderParam[2] + (float2 - lowRiderParam[2]) * float3;
                } else {
                    lowRiderParam[2] = lowRiderParam[2] + (0.0F - lowRiderParam[2]) * 0.05F;
                }

                if (GameKeyboard.isKeyDown(76)) {
                    lowRiderParam[3] = lowRiderParam[3] + (float2 - lowRiderParam[3]) * float3;
                } else {
                    lowRiderParam[3] = lowRiderParam[3] + (0.0F - lowRiderParam[3]) * 0.05F;
                }

                float0[23] = lowRiderParam[0];
                float0[22] = lowRiderParam[1];
                float0[21] = lowRiderParam[2];
                float0[20] = lowRiderParam[3];
            }

            Bullet.setVehicleParams(this.VehicleID, float0);
        }
    }

    private void updateBulletStatsWheel(int int1, float[] float0, Vector3f vector3f1, float float1, int int2, double double1, double double0) {
        int int0 = int1 * 6;
        VehicleScript.Wheel wheel = this.script.getWheel(int1);
        Vector3f vector3f0 = this.getWorldPos(wheel.offset.x, wheel.offset.y, wheel.offset.z, vector3f1);
        VehiclePart vehiclePart0 = this.getPartById("Tire" + wheel.getId());
        VehiclePart vehiclePart1 = this.getPartById("Suspension" + wheel.getId());
        if (vehiclePart0 != null && vehiclePart0.getInventoryItem() != null) {
            float0[int0 + 0] = 1.0F;
            float0[int0 + 1] = Math.min(vehiclePart0.getContainerContentAmount() / (float)(vehiclePart0.getContainerCapacity() - 10), 1.0F);
            float0[int0 + 2] = float1 * vehiclePart0.getWheelFriction();
            if (vehiclePart1 != null && vehiclePart1.getInventoryItem() != null) {
                float0[int0 + 3] = vehiclePart1.getSuspensionDamping();
                float0[int0 + 4] = vehiclePart1.getSuspensionCompression();
            } else {
                float0[int0 + 3] = 0.1F;
                float0[int0 + 4] = 0.1F;
            }

            if (Rand.Next(int2) == 0) {
                float0[int0 + 5] = (float)(Math.sin(double1 * (double)vector3f0.x()) * Math.sin(double1 * (double)vector3f0.y()) * double0);
            } else {
                float0[int0 + 5] = 0.0F;
            }
        } else {
            float0[int0 + 0] = 0.0F;
            float0[int0 + 1] = 30.0F;
            float0[int0 + 2] = 0.0F;
            float0[int0 + 3] = 2.88F;
            float0[int0 + 4] = 3.83F;
            if (Rand.Next(int2) == 0) {
                float0[int0 + 5] = (float)(Math.sin(double1 * (double)vector3f0.x()) * Math.sin(double1 * (double)vector3f0.y()) * double0);
            } else {
                float0[int0 + 5] = 0.0F;
            }
        }

        if (this.forcedFriction > -1.0F) {
            float0[int0 + 2] = this.forcedFriction;
        }
    }

    public void setActiveInBullet(boolean active) {
        if (active || !this.isEngineRunning()) {
            ;
        }
    }

    public boolean areAllDoorsLocked() {
        for (int _int = 0; _int < this.getMaxPassengers(); _int++) {
            VehiclePart vehiclePart = this.getPassengerDoor(_int);
            if (vehiclePart != null && vehiclePart.getDoor() != null && !vehiclePart.getDoor().isLocked()) {
                return false;
            }
        }

        return true;
    }

    public boolean isAnyDoorLocked() {
        for (int _int = 0; _int < this.getMaxPassengers(); _int++) {
            VehiclePart vehiclePart = this.getPassengerDoor(_int);
            if (vehiclePart != null && vehiclePart.getDoor() != null && vehiclePart.getDoor().isLocked()) {
                return true;
            }
        }

        return false;
    }

    public float getRemainingFuelPercentage() {
        VehiclePart vehiclePart = this.getPartById("GasTank");
        return vehiclePart == null ? 0.0F : vehiclePart.getContainerContentAmount() / (float)vehiclePart.getContainerCapacity() * 100.0F;
    }

    public int getMechanicalID() {
        return this.mechanicalID;
    }

    public void setMechanicalID(int _mechanicalID) {
        this.mechanicalID = _mechanicalID;
    }

    public boolean needPartsUpdate() {
        return this.needPartsUpdate;
    }

    public void setNeedPartsUpdate(boolean _needPartsUpdate) {
        this.needPartsUpdate = _needPartsUpdate;
    }

    public VehiclePart getHeater() {
        return this.getPartById("Heater");
    }

    public int windowsOpen() {
        int int0 = 0;

        for (int int1 = 0; int1 < this.getPartCount(); int1++) {
            VehiclePart vehiclePart = this.getPartByIndex(int1);
            if (vehiclePart.window != null && vehiclePart.window.open) {
                int0++;
            }
        }

        return int0;
    }

    public boolean isAlarmed() {
        return this.alarmed;
    }

    public void setAlarmed(boolean _alarmed) {
        this.alarmed = _alarmed;
        if (_alarmed) {
            this.setPreviouslyEntered(false);
        }
    }

    public void triggerAlarm() {
        if (this.alarmed) {
            this.alarmed = false;
            this.alarmTime = Rand.Next(1500, 3000);
            this.alarmAccumulator = 0.0F;
        }
    }

    private void doAlarm() {
        if (this.alarmTime > 0) {
            if (this.getBatteryCharge() <= 0.0F) {
                if (this.soundHornOn) {
                    this.onHornStop();
                }

                this.alarmTime = -1;
                return;
            }

            this.alarmAccumulator = this.alarmAccumulator + zombie.GameTime.instance.getMultiplier() / 1.6F;
            if (this.alarmAccumulator >= (float)this.alarmTime) {
                this.onHornStop();
                this.setHeadlightsOn(false);
                this.alarmTime = -1;
                return;
            }

            int _int = (int)this.alarmAccumulator / 20;
            if (!this.soundHornOn && _int % 2 == 0) {
                this.onHornStart();
                this.setHeadlightsOn(true);
            }

            if (this.soundHornOn && _int % 2 == 1) {
                this.onHornStop();
                this.setHeadlightsOn(false);
            }
        }
    }

    public boolean isMechanicUIOpen() {
        return this.mechanicUIOpen;
    }

    public void setMechanicUIOpen(boolean _mechanicUIOpen) {
        this.mechanicUIOpen = _mechanicUIOpen;
    }

    public void damagePlayers(float damage) {
        if (zombie.SandboxOptions.instance.PlayerDamageFromCrash.getValue()) {
            if (!GameClient.bClient) {
                for (int _int = 0; _int < this.passengers.length; _int++) {
                    if (this.getPassenger(_int).character != null) {
                        IsoGameCharacter isoGameCharacter = this.getPassenger(_int).character;
                        if (GameServer.bServer && isoGameCharacter instanceof IsoPlayer) {
                            GameServer.sendPlayerDamagedByCarCrash((IsoPlayer)isoGameCharacter, damage);
                        } else {
                            this.addRandomDamageFromCrash(isoGameCharacter, damage);
                            LuaEventManager.triggerEvent("OnPlayerGetDamage", isoGameCharacter, "CARCRASHDAMAGE", damage);
                        }
                    }
                }
            }
        }
    }

    public void addRandomDamageFromCrash(IsoGameCharacter chr, float damage) {
        int int0 = 1;
        if (damage > 40.0F) {
            int0 = Rand.Next(1, 3);
        }

        if (damage > 70.0F) {
            int0 = Rand.Next(2, 4);
        }

        int int1 = 0;

        for (int int2 = 0; int2 < chr.getVehicle().getPartCount(); int2++) {
            VehiclePart vehiclePart = chr.getVehicle().getPartByIndex(int2);
            if (vehiclePart.window != null && vehiclePart.getCondition() < 15) {
                int1++;
            }
        }

        for (int int3 = 0; int3 < int0; int3++) {
            int int4 = Rand.Next(BodyPartType.ToIndex(BodyPartType.Hand_L), BodyPartType.ToIndex(BodyPartType.MAX));
            BodyPart bodyPart = chr.getBodyDamage().getBodyPart(BodyPartType.FromIndex(int4));
            float _float = Math.max(Rand.Next(damage - 15.0F, damage), 5.0F);
            if (chr.Traits.FastHealer.isSet()) {
                _float = (float)((double)_float * 0.8);
            } else if (chr.Traits.SlowHealer.isSet()) {
                _float = (float)((double)_float * 1.2);
            }

            switch (zombie.SandboxOptions.instance.InjurySeverity.getValue()) {
                case 1:
                    _float *= 0.5F;
                    break;
                case 3:
                    _float *= 1.5F;
            }

            _float *= this.getScript().getPlayerDamageProtection();
            _float = (float)((double)_float * 0.9);
            bodyPart.AddDamage(_float);
            if (_float > 40.0F && Rand.Next(12) == 0) {
                bodyPart.generateDeepWound();
            } else if (_float > 50.0F && Rand.Next(10) == 0 && zombie.SandboxOptions.instance.BoneFracture.getValue()) {
                if (bodyPart.getType() != BodyPartType.Neck && bodyPart.getType() != BodyPartType.Groin) {
                    bodyPart.setFractureTime(Rand.Next(Rand.Next(10.0F, _float + 10.0F), Rand.Next(_float + 20.0F, _float + 30.0F)));
                } else {
                    bodyPart.generateDeepWound();
                }
            }

            if (_float > 30.0F && Rand.Next(12 - int1) == 0) {
                bodyPart = chr.getBodyDamage().setScratchedWindow();
                if (Rand.Next(5) == 0) {
                    bodyPart.generateDeepWound();
                    bodyPart.setHaveGlass(true);
                }
            }
        }
    }

    public void hitVehicle(IsoGameCharacter attacker, HandWeapon weapon) {
        float _float = 1.0F;
        if (weapon == null) {
            weapon = (HandWeapon)InventoryItemFactory.CreateItem("Base.BareHands");
        }

        _float = (float)weapon.getDoorDamage();
        if (attacker.isCriticalHit()) {
            _float *= 10.0F;
        }

        VehiclePart vehiclePart0 = this.getNearestBodyworkPart(attacker);
        if (vehiclePart0 != null) {
            VehicleWindow vehicleWindow = vehiclePart0.getWindow();

            for (int _int = 0; _int < vehiclePart0.getChildCount(); _int++) {
                VehiclePart vehiclePart1 = vehiclePart0.getChild(_int);
                if (vehiclePart1.getWindow() != null) {
                    vehicleWindow = vehiclePart1.getWindow();
                    break;
                }
            }

            if (vehicleWindow != null && vehicleWindow.getHealth() > 0) {
                vehicleWindow.damage((int)_float);
                this.transmitPartWindow(vehiclePart0);
                if (vehicleWindow.getHealth() == 0) {
                    VehicleManager.sendSoundFromServer(this, (byte)1);
                }
            } else {
                vehiclePart0.setCondition(vehiclePart0.getCondition() - (int)_float);
                this.transmitPartItem(vehiclePart0);
            }

            vehiclePart0.updateFlags = (short)(vehiclePart0.updateFlags | 2048);
            this.updateFlags = (short)(this.updateFlags | 2048);
        } else {
            Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            this.getLocalPos(attacker.getX(), attacker.getY(), attacker.getZ(), vector3f);
            boolean _boolean = vector3f.x > 0.0F;
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
            if (_boolean) {
                this.addDamageFront((int)_float);
            } else {
                this.addDamageRear((int)_float);
            }

            this.updateFlags = (short)(this.updateFlags | 2048);
        }
    }

    public boolean isTrunkLocked() {
        VehiclePart vehiclePart = this.getPartById("TrunkDoor");
        if (vehiclePart == null) {
            vehiclePart = this.getPartById("DoorRear");
        }

        return vehiclePart != null && vehiclePart.getDoor() != null && vehiclePart.getInventoryItem() != null ? vehiclePart.getDoor().isLocked() : false;
    }

    public void setTrunkLocked(boolean locked) {
        VehiclePart vehiclePart = this.getPartById("TrunkDoor");
        if (vehiclePart == null) {
            vehiclePart = this.getPartById("DoorRear");
        }

        if (vehiclePart != null && vehiclePart.getDoor() != null && vehiclePart.getInventoryItem() != null) {
            vehiclePart.getDoor().setLocked(locked);
            if (GameServer.bServer) {
                this.transmitPartDoor(vehiclePart);
            }
        }
    }

    public VehiclePart getNearestBodyworkPart(IsoGameCharacter chr) {
        for (int _int = 0; _int < this.getPartCount(); _int++) {
            VehiclePart vehiclePart = this.getPartByIndex(_int);
            if (("door".equals(vehiclePart.getCategory()) || "bodywork".equals(vehiclePart.getCategory()))
                && this.isInArea(vehiclePart.getArea(), chr)
                && vehiclePart.getCondition() > 0) {
                return vehiclePart;
            }
        }

        return null;
    }

    public double getSirenStartTime() {
        return this.sirenStartTime;
    }

    public void setSirenStartTime(double worldAgeHours) {
        this.sirenStartTime = worldAgeHours;
    }

    public boolean sirenShutoffTimeExpired() {
        double double0 = zombie.SandboxOptions.instance.SirenShutoffHours.getValue();
        if (double0 <= 0.0) {
            return false;
        } else {
            double double1 = zombie.GameTime.instance.getWorldAgeHours();
            if (this.sirenStartTime > double1) {
                this.sirenStartTime = double1;
            }

            return this.sirenStartTime + double0 < double1;
        }
    }

    public void repair() {
        for (int _int = 0; _int < this.getPartCount(); _int++) {
            VehiclePart vehiclePart = this.getPartByIndex(_int);
            vehiclePart.repair();
        }

        this.rust = 0.0F;
        this.transmitRust();
        this.bloodIntensity.clear();
        this.transmitBlood();
        this.doBloodOverlay();
    }

    public boolean isAnyListenerInside() {
        for (int _int = 0; _int < this.getMaxPassengers(); _int++) {
            IsoGameCharacter isoGameCharacter = this.getCharacter(_int);
            if (isoGameCharacter instanceof IsoPlayer && ((IsoPlayer)isoGameCharacter).isLocalPlayer() && !isoGameCharacter.Traits.Deaf.isSet()) {
                return true;
            }
        }

        return false;
    }

    public boolean couldCrawlerAttackPassenger(IsoGameCharacter chr) {
        int _int = this.getSeat(chr);
        return _int == -1 ? false : false;
    }

    public boolean isGoodCar() {
        return this.isGoodCar;
    }

    public void setGoodCar(boolean _isGoodCar) {
        this.isGoodCar = _isGoodCar;
    }

    public InventoryItem getCurrentKey() {
        return this.currentKey;
    }

    public void setCurrentKey(InventoryItem _currentKey) {
        this.currentKey = _currentKey;
    }

    public boolean isInForest() {
        return this.getSquare() != null
            && this.getSquare().getZone() != null
            && (
                "Forest".equals(this.getSquare().getZone().getType())
                    || "DeepForest".equals(this.getSquare().getZone().getType())
                    || "FarmLand".equals(this.getSquare().getZone().getType())
            );
    }

    public float getOffroadEfficiency() {
        return this.isInForest() ? this.script.getOffroadEfficiency() * 1.5F : this.script.getOffroadEfficiency() * 2.0F;
    }

    public void doChrHitImpulse(IsoObject chr) {
        float float0 = 22.0F;
        Vector3f vector3f0 = this.getLinearVelocity(((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
        vector3f0.y = 0.0F;
        Vector3f vector3f1 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
        vector3f1.set(this.x - chr.getX(), 0.0F, this.z - chr.getY());
        vector3f1.normalize();
        vector3f0.mul(vector3f1);
        ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
        float float1 = vector3f0.length();
        float1 = Math.min(float1, float0);
        if (float1 < 0.05F) {
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
        } else {
            if (GameServer.bServer) {
                if (chr instanceof IsoZombie) {
                    ((IsoZombie)chr).setThumpFlag(1);
                }
            } else {
                zombie.SoundManager.instance.PlayWorldSound("ZombieThumpGeneric", chr.square, 0.0F, 20.0F, 0.9F, true);
            }

            Vector3f vector3f2 = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            vector3f2.set(this.x - chr.getX(), 0.0F, this.y - chr.getY());
            vector3f2.normalize();
            vector3f0.normalize();
            float float2 = vector3f0.dot(vector3f2);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f0);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f2);
            this.ApplyImpulse(chr, this.getFudgedMass() * 3.0F * float1 / float0 * Math.abs(float2));
        }
    }

    public boolean isDoColor() {
        return this.doColor;
    }

    public void setDoColor(boolean _doColor) {
        this.doColor = _doColor;
    }

    public float getBrakeSpeedBetweenUpdate() {
        return this.brakeBetweenUpdatesSpeed;
    }

    @Override
    public IsoGridSquare getSquare() {
        return this.getCell().getGridSquare((double)this.x, (double)this.y, (double)this.z);
    }

    public void setColor(float value, float saturation, float hue) {
        this.colorValue = value;
        this.colorSaturation = saturation;
        this.colorHue = hue;
    }

    public void setColorHSV(float hue, float saturation, float value) {
        this.colorHue = hue;
        this.colorSaturation = saturation;
        this.colorValue = value;
    }

    public float getColorHue() {
        return this.colorHue;
    }

    public float getColorSaturation() {
        return this.colorSaturation;
    }

    public float getColorValue() {
        return this.colorValue;
    }

    public boolean isRemovedFromWorld() {
        return this.removedFromWorld;
    }

    public float getInsideTemperature() {
        VehiclePart vehiclePart = this.getPartById("PassengerCompartment");
        float _float = 0.0F;
        if (vehiclePart != null && vehiclePart.getModData() != null) {
            if (vehiclePart.getModData().rawget("temperature") != null) {
                _float += ((Double)vehiclePart.getModData().rawget("temperature")).floatValue();
            }

            if (vehiclePart.getModData().rawget("windowtemperature") != null) {
                _float += ((Double)vehiclePart.getModData().rawget("windowtemperature")).floatValue();
            }
        }

        return _float;
    }

    public AnimationPlayer getAnimationPlayer() {
        String string = this.getScript().getModel().file;
        Model model = ModelManager.instance.getLoadedModel(string);
        if (model != null && !model.bStatic) {
            if (this.m_animPlayer != null && this.m_animPlayer.getModel() != model) {
                this.m_animPlayer = Pool.tryRelease(this.m_animPlayer);
            }

            if (this.m_animPlayer == null) {
                this.m_animPlayer = AnimationPlayer.alloc(model);
            }

            return this.m_animPlayer;
        } else {
            return null;
        }
    }

    public void releaseAnimationPlayers() {
        this.m_animPlayer = Pool.tryRelease(this.m_animPlayer);
        PZArrayUtil.forEach(this.models, BaseVehicle.ModelInfo::releaseAnimationPlayer);
    }

    public void setAddThumpWorldSound(boolean add) {
        this.bAddThumpWorldSound = add;
    }

    @Override
    public void Thump(IsoMovingObject thumper) {
        VehiclePart vehiclePart0 = this.getPartById("lightbar");
        if (vehiclePart0 != null) {
            if (vehiclePart0.getCondition() <= 0) {
                thumper.setThumpTarget(null);
            }

            VehiclePart vehiclePart1 = this.getUseablePart((IsoGameCharacter)thumper);
            if (vehiclePart1 != null) {
                vehiclePart1.setCondition(vehiclePart1.getCondition() - Rand.Next(1, 5));
            }

            vehiclePart0.setCondition(vehiclePart0.getCondition() - Rand.Next(1, 5));
        }
    }

    @Override
    public void WeaponHit(IsoGameCharacter chr, HandWeapon weapon) {
    }

    @Override
    public Thumpable getThumpableFor(IsoGameCharacter chr) {
        return null;
    }

    @Override
    public float getThumpCondition() {
        return 1.0F;
    }

    public boolean isRegulator() {
        return this.regulator;
    }

    public void setRegulator(boolean _regulator) {
        this.regulator = _regulator;
    }

    public float getRegulatorSpeed() {
        return this.regulatorSpeed;
    }

    public void setRegulatorSpeed(float _regulatorSpeed) {
        this.regulatorSpeed = _regulatorSpeed;
    }

    public float getCurrentSpeedForRegulator() {
        return (float)Math.max(5.0 * Math.floor((double)(this.jniSpeed / 5.0F)), 5.0);
    }

    public void setVehicleTowing(BaseVehicle vehicleB, String attachmentA, String attachmentB) {
        this.vehicleTowing = vehicleB;
        this.vehicleTowingID = this.vehicleTowing == null ? -1 : this.vehicleTowing.getSqlId();
        this.towAttachmentSelf = attachmentA;
        this.towAttachmentOther = attachmentB;
        this.towConstraintZOffset = 0.0F;
    }

    public void setVehicleTowedBy(BaseVehicle vehicleA, String attachmentA, String attachmentB) {
        this.vehicleTowedBy = vehicleA;
        this.vehicleTowedByID = this.vehicleTowedBy == null ? -1 : this.vehicleTowedBy.getSqlId();
        this.towAttachmentSelf = attachmentB;
        this.towAttachmentOther = attachmentA;
        this.towConstraintZOffset = 0.0F;
    }

    public BaseVehicle getVehicleTowing() {
        return this.vehicleTowing;
    }

    public BaseVehicle getVehicleTowedBy() {
        return this.vehicleTowedBy;
    }

    public boolean attachmentExist(String attachmentName) {
        VehicleScript vehicleScript = this.getScript();
        if (vehicleScript == null) {
            return false;
        } else {
            ModelAttachment modelAttachment = vehicleScript.getAttachmentById(attachmentName);
            return modelAttachment != null;
        }
    }

    public Vector3f getAttachmentLocalPos(String string, Vector3f vector3f) {
        VehicleScript vehicleScript = this.getScript();
        if (vehicleScript == null) {
            return null;
        } else {
            ModelAttachment modelAttachment = vehicleScript.getAttachmentById(string);
            if (modelAttachment == null) {
                return null;
            } else {
                vector3f.set(modelAttachment.getOffset());
                return vehicleScript.getModel() == null ? vector3f : vector3f.add(vehicleScript.getModel().getOffset());
            }
        }
    }

    public Vector3f getAttachmentWorldPos(String string, Vector3f vector3f) {
        vector3f = this.getAttachmentLocalPos(string, vector3f);
        return vector3f == null ? null : this.getWorldPos(vector3f, vector3f);
    }

    public void setForceBrake() {
        this.getController().clientControls.forceBrake = System.currentTimeMillis();
    }

    public Vector3f getTowingLocalPos(String string, Vector3f vector3f) {
        return this.getAttachmentLocalPos(string, vector3f);
    }

    public Vector3f getTowedByLocalPos(String string, Vector3f vector3f) {
        return this.getAttachmentLocalPos(string, vector3f);
    }

    public Vector3f getTowingWorldPos(String string, Vector3f vector3f) {
        vector3f = this.getTowingLocalPos(string, vector3f);
        return vector3f == null ? null : this.getWorldPos(vector3f, vector3f);
    }

    public Vector3f getTowedByWorldPos(String string, Vector3f vector3f) {
        vector3f = this.getTowedByLocalPos(string, vector3f);
        return vector3f == null ? null : this.getWorldPos(vector3f, vector3f);
    }

    public Vector3f getPlayerTrailerLocalPos(String string, boolean _boolean, Vector3f vector3f2) {
        ModelAttachment modelAttachment = this.getScript().getAttachmentById(string);
        if (modelAttachment == null) {
            return null;
        } else {
            Vector3f vector3f0 = this.getScript().getExtents();
            Vector3f vector3f1 = this.getScript().getCenterOfMassOffset();
            float _float = vector3f1.x + vector3f0.x / 2.0F + 0.3F + 0.05F;
            if (!_boolean) {
                _float *= -1.0F;
            }

            return modelAttachment.getOffset().z > 0.0F
                ? vector3f2.set(_float, 0.0F, vector3f1.z + vector3f0.z / 2.0F + 0.3F + 0.05F)
                : vector3f2.set(_float, 0.0F, vector3f1.z - (vector3f0.z / 2.0F + 0.3F + 0.05F));
        }
    }

    public Vector3f getPlayerTrailerWorldPos(String string, boolean boolean0, Vector3f vector3f0) {
        vector3f0 = this.getPlayerTrailerLocalPos(string, boolean0, vector3f0);
        if (vector3f0 == null) {
            return null;
        } else {
            this.getWorldPos(vector3f0, vector3f0);
            vector3f0.z = (float)((int)this.z);
            Vector3f vector3f1 = this.getTowingWorldPos(string, ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc());
            boolean boolean1 = PolygonalMap2.instance.lineClearCollide(vector3f0.x, vector3f0.y, vector3f1.x, vector3f1.y, (int)this.z, this, false, false);
            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f1);
            return boolean1 ? null : vector3f0;
        }
    }

    private void drawTowingRope() {
        BaseVehicle baseVehicle0 = this.getVehicleTowing();
        if (baseVehicle0 != null) {
            BaseVehicle.Vector3fObjectPool vector3fObjectPool = (BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get();
            Vector3f vector3f0 = this.getAttachmentWorldPos("trailer", vector3fObjectPool.alloc());
            Vector3f vector3f1 = this.getAttachmentWorldPos("trailerfront", vector3fObjectPool.alloc());
            ModelAttachment modelAttachment = this.script.getAttachmentById("trailerfront");
            if (modelAttachment != null) {
                vector3f1.set(modelAttachment.getOffset());
            }

            Vector2 vector2 = new Vector2();
            vector2.x = baseVehicle0.x;
            vector2.y = baseVehicle0.y;
            vector2.x = vector2.x - this.x;
            vector2.y = vector2.y - this.y;
            vector2.setLength(2.0F);
            this.drawDirectionLine(vector2, vector2.getLength(), 1.0F, 0.5F, 0.5F);
        }
    }

    public void drawDirectionLine(Vector2 dir, float length, float r, float g, float b) {
        float float0 = this.x + dir.x * length;
        float float1 = this.y + dir.y * length;
        float float2 = IsoUtils.XToScreenExact(this.x, this.y, this.z, 0);
        float float3 = IsoUtils.YToScreenExact(this.x, this.y, this.z, 0);
        float float4 = IsoUtils.XToScreenExact(float0, float1, this.z, 0);
        float float5 = IsoUtils.YToScreenExact(float0, float1, this.z, 0);
        LineDrawer.drawLine(float2, float3, float4, float5, r, g, b, 0.5F, 1);
    }

    public void addPointConstraint(IsoPlayer player, BaseVehicle vehicleB, String attachmentA, String attachmentB) {
        this.addPointConstraint(player, vehicleB, attachmentA, attachmentB, false);
    }

    public void addPointConstraint(IsoPlayer player, BaseVehicle vehicleB, String attachmentA, String attachmentB, Boolean remote) {
        if (vehicleB == null
            || player != null
                && (
                    IsoUtils.DistanceToSquared(player.x, player.y, this.x, this.y) > 100.0F
                        || IsoUtils.DistanceToSquared(player.x, player.y, vehicleB.x, vehicleB.y) > 100.0F
                )) {
            DebugLog.General.warn("The " + player.getUsername() + " user attached vehicles at a long distance");
        }

        this.breakConstraint(true, remote);
        vehicleB.breakConstraint(true, remote);
        BaseVehicle.Vector3fObjectPool vector3fObjectPool = (BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get();
        Vector3f vector3f0 = this.getTowingLocalPos(attachmentA, vector3fObjectPool.alloc());
        Vector3f vector3f1 = vehicleB.getTowedByLocalPos(attachmentB, vector3fObjectPool.alloc());
        if (vector3f0 != null && vector3f1 != null) {
            if (!GameServer.bServer) {
                if (!this.getScriptName().contains("Trailer") && !vehicleB.getScriptName().contains("Trailer")) {
                    this.constraintTowing = Bullet.addRopeConstraint(
                        this.VehicleID, vehicleB.VehicleID, vector3f0.x, vector3f0.y, vector3f0.z, vector3f1.x, vector3f1.y, vector3f1.z, 1.5F
                    );
                } else {
                    this.constraintTowing = Bullet.addPointConstraint(
                        this.VehicleID, vehicleB.VehicleID, vector3f0.x, vector3f0.y, vector3f0.z, vector3f1.x, vector3f1.y, vector3f1.z
                    );
                }
            }

            vehicleB.constraintTowing = this.constraintTowing;
            this.setVehicleTowing(vehicleB, attachmentA, attachmentB);
            vehicleB.setVehicleTowedBy(this, attachmentA, attachmentB);
            vector3fObjectPool.release(vector3f0);
            vector3fObjectPool.release(vector3f1);
            this.constraintChanged();
            vehicleB.constraintChanged();
            if (GameServer.bServer
                && player != null
                && this.netPlayerAuthorization == BaseVehicle.Authorization.Server
                && vehicleB.netPlayerAuthorization == BaseVehicle.Authorization.Server) {
                this.setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, player.OnlineID);
                this.authSimulationTime = System.currentTimeMillis();
                vehicleB.setNetPlayerAuthorization(BaseVehicle.Authorization.LocalCollide, player.OnlineID);
                vehicleB.authSimulationTime = System.currentTimeMillis();
            }

            if (GameServer.bServer && !remote) {
                VehicleManager.instance.sendTowing(this, vehicleB, attachmentA, attachmentB);
            }
        } else {
            if (vector3f0 != null) {
                vector3fObjectPool.release(vector3f0);
            }

            if (vector3f1 != null) {
                vector3fObjectPool.release(vector3f1);
            }
        }
    }

    public void authorizationChanged(IsoGameCharacter character) {
        if (character != null) {
            this.setNetPlayerAuthorization(BaseVehicle.Authorization.Local, character.getOnlineID());
        } else {
            this.setNetPlayerAuthorization(BaseVehicle.Authorization.Server, -1);
        }
    }

    public void constraintChanged() {
        long _long = System.currentTimeMillis();
        this.setPhysicsActive(true);
        this.constraintChangedTime = _long;
        if (GameServer.bServer) {
            if (this.getVehicleTowing() != null) {
                this.authorizationChanged(this.getDriver());
                this.getVehicleTowing().authorizationChanged(this.getDriver());
            } else if (this.getVehicleTowedBy() != null) {
                this.authorizationChanged(this.getVehicleTowedBy().getDriver());
                this.getVehicleTowedBy().authorizationChanged(this.getVehicleTowedBy().getDriver());
            } else {
                this.authorizationChanged(this.getDriver());
            }
        }
    }

    public void breakConstraint(boolean forgetID, boolean remote) {
        if (GameServer.bServer || this.constraintTowing != -1) {
            if (!GameServer.bServer) {
                Bullet.removeConstraint(this.constraintTowing);
            }

            this.constraintTowing = -1;
            if (this.vehicleTowing != null) {
                if (GameServer.bServer && !remote) {
                    VehicleManager.instance.sendDetachTowing(this, this.vehicleTowing);
                }

                this.vehicleTowing.vehicleTowedBy = null;
                this.vehicleTowing.constraintTowing = -1;
                if (forgetID) {
                    this.vehicleTowingID = -1;
                    this.vehicleTowing.vehicleTowedByID = -1;
                }

                this.vehicleTowing.constraintChanged();
                this.vehicleTowing = null;
            }

            if (this.vehicleTowedBy != null) {
                if (GameServer.bServer && !remote) {
                    VehicleManager.instance.sendDetachTowing(this.vehicleTowedBy, this);
                }

                this.vehicleTowedBy.vehicleTowing = null;
                this.vehicleTowedBy.constraintTowing = -1;
                if (forgetID) {
                    this.vehicleTowedBy.vehicleTowingID = -1;
                    this.vehicleTowedByID = -1;
                }

                this.vehicleTowedBy.constraintChanged();
                this.vehicleTowedBy = null;
            }

            this.constraintChanged();
        }
    }

    public boolean canAttachTrailer(BaseVehicle vehicleB, String attachmentA, String attachmentB) {
        return this.canAttachTrailer(vehicleB, attachmentA, attachmentB, false);
    }

    public boolean canAttachTrailer(BaseVehicle vehicleB, String attachmentA, String attachmentB, boolean reconnect) {
        if (this == vehicleB || this.physics == null || this.constraintTowing != -1) {
            return false;
        } else if (vehicleB != null && vehicleB.physics != null && vehicleB.constraintTowing == -1) {
            BaseVehicle.Vector3fObjectPool vector3fObjectPool = (BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get();
            Vector3f vector3f0 = this.getTowingWorldPos(attachmentA, vector3fObjectPool.alloc());
            Vector3f vector3f1 = vehicleB.getTowedByWorldPos(attachmentB, vector3fObjectPool.alloc());
            if (vector3f0 != null && vector3f1 != null) {
                float _float = IsoUtils.DistanceToSquared(vector3f0.x, vector3f0.y, 0.0F, vector3f1.x, vector3f1.y, 0.0F);
                vector3fObjectPool.release(vector3f0);
                vector3fObjectPool.release(vector3f1);
                ModelAttachment modelAttachment0 = this.script.getAttachmentById(attachmentA);
                ModelAttachment modelAttachment1 = vehicleB.script.getAttachmentById(attachmentB);
                if (modelAttachment0 != null && modelAttachment0.getCanAttach() != null && !modelAttachment0.getCanAttach().contains(attachmentB)) {
                    return false;
                } else if (modelAttachment1 != null && modelAttachment1.getCanAttach() != null && !modelAttachment1.getCanAttach().contains(attachmentA)) {
                    return false;
                } else {
                    DebugLog.Vehicle.trace("vidA=%d (%s) vidB=%d (%s) dist: %f", this.getId(), attachmentA, vehicleB.getId(), attachmentB, _float);
                    boolean _boolean = this.getScriptName().contains("Trailer") || vehicleB.getScriptName().contains("Trailer");
                    return _float < (reconnect ? 10.0F : (_boolean ? 1.0F : 4.0F));
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    private void tryReconnectToTowedVehicle() {
        if (GameClient.bClient) {
            short _short = VehicleManager.instance.getTowedVehicleID(this.VehicleID);
            if (_short != -1) {
                BaseVehicle baseVehicle1 = VehicleManager.instance.getVehicleByID(_short);
                if (baseVehicle1 != null) {
                    if (this.canAttachTrailer(baseVehicle1, this.towAttachmentSelf, this.towAttachmentOther, true)) {
                        this.addPointConstraint(null, baseVehicle1, this.towAttachmentSelf, this.towAttachmentOther, true);
                    }
                }
            }
        } else if (this.vehicleTowing == null) {
            if (this.vehicleTowingID != -1) {
                BaseVehicle baseVehicle2 = null;
                ArrayList arrayList = IsoWorld.instance.CurrentCell.getVehicles();

                for (int _int = 0; _int < arrayList.size(); _int++) {
                    BaseVehicle baseVehicle3 = (BaseVehicle)arrayList.get(_int);
                    if (baseVehicle3.getSqlId() == this.vehicleTowingID) {
                        baseVehicle2 = baseVehicle3;
                        break;
                    }
                }

                if (baseVehicle2 != null) {
                    if (this.canAttachTrailer(baseVehicle2, this.towAttachmentSelf, this.towAttachmentOther, true)) {
                        this.addPointConstraint(null, baseVehicle2, this.towAttachmentSelf, this.towAttachmentOther, false);
                    }
                }
            }
        }
    }

    public void positionTrailer(BaseVehicle trailer) {
        if (trailer != null) {
            BaseVehicle.Vector3fObjectPool vector3fObjectPool = (BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get();
            Vector3f vector3f0 = this.getTowingWorldPos("trailer", vector3fObjectPool.alloc());
            Vector3f vector3f1 = trailer.getTowedByWorldPos("trailer", vector3fObjectPool.alloc());
            if (vector3f0 != null && vector3f1 != null) {
                vector3f1.sub(trailer.x, trailer.y, trailer.z);
                vector3f0.sub(vector3f1);
                Transform transform = trailer.getWorldTransform(this.tempTransform);
                transform.origin
                    .set(vector3f0.x - WorldSimulation.instance.offsetX, trailer.jniTransform.origin.y, vector3f0.y - WorldSimulation.instance.offsetY);
                trailer.setWorldTransform(transform);
                trailer.setX(vector3f0.x);
                trailer.setLx(vector3f0.x);
                trailer.setY(vector3f0.y);
                trailer.setLy(vector3f0.y);
                trailer.setCurrent(this.getCell().getGridSquare((double)vector3f0.x, (double)vector3f0.y, 0.0));
                this.addPointConstraint(null, trailer, "trailer", "trailer");
                vector3fObjectPool.release(vector3f0);
                vector3fObjectPool.release(vector3f1);
            }
        }
    }

    public String getTowAttachmentSelf() {
        return this.towAttachmentSelf;
    }

    public String getTowAttachmentOther() {
        return this.towAttachmentOther;
    }

    public VehicleEngineRPM getVehicleEngineRPM() {
        if (this.vehicleEngineRPM == null) {
            this.vehicleEngineRPM = ScriptManager.instance.getVehicleEngineRPM(this.getScript().getEngineRPMType());
            if (this.vehicleEngineRPM == null) {
                DebugLog.General.warn("unknown vehicleEngineRPM \"%s\"", this.getScript().getEngineRPMType());
                this.vehicleEngineRPM = new VehicleEngineRPM();
            }
        }

        return this.vehicleEngineRPM;
    }

    public FMODParameterList getFMODParameters() {
        return this.fmodParameters;
    }

    public void startEvent(long eventInstance, GameSoundClip clip, BitSet parameterSet) {
        FMODParameterList fMODParameterList = this.getFMODParameters();
        ArrayList arrayList = clip.eventDescription.parameters;

        for (int _int = 0; _int < arrayList.size(); _int++) {
            FMOD_STUDIO_PARAMETER_DESCRIPTION fMOD_STUDIO_PARAMETER_DESCRIPTION = (FMOD_STUDIO_PARAMETER_DESCRIPTION)arrayList.get(_int);
            if (!parameterSet.get(fMOD_STUDIO_PARAMETER_DESCRIPTION.globalIndex)) {
                FMODParameter fMODParameter = fMODParameterList.get(fMOD_STUDIO_PARAMETER_DESCRIPTION);
                if (fMODParameter != null) {
                    fMODParameter.startEventInstance(eventInstance);
                }
            }
        }
    }

    public void updateEvent(long eventInstance, GameSoundClip clip) {
    }

    public void stopEvent(long eventInstance, GameSoundClip clip, BitSet parameterSet) {
        FMODParameterList fMODParameterList = this.getFMODParameters();
        ArrayList arrayList = clip.eventDescription.parameters;

        for (int _int = 0; _int < arrayList.size(); _int++) {
            FMOD_STUDIO_PARAMETER_DESCRIPTION fMOD_STUDIO_PARAMETER_DESCRIPTION = (FMOD_STUDIO_PARAMETER_DESCRIPTION)arrayList.get(_int);
            if (!parameterSet.get(fMOD_STUDIO_PARAMETER_DESCRIPTION.globalIndex)) {
                FMODParameter fMODParameter = fMODParameterList.get(fMOD_STUDIO_PARAMETER_DESCRIPTION);
                if (fMODParameter != null) {
                    fMODParameter.stopEventInstance(eventInstance);
                }
            }
        }
    }

    private void stopEngineSounds() {
        if (this.emitter != null) {
            for (int _int = 0; _int < this.new_EngineSoundId.length; _int++) {
                if (this.new_EngineSoundId[_int] != 0L) {
                    this.getEmitter().stopSound(this.new_EngineSoundId[_int]);
                    this.new_EngineSoundId[_int] = 0L;
                }
            }

            if (this.combinedEngineSound != 0L) {
                if (this.getEmitter().hasSustainPoints(this.combinedEngineSound)) {
                    this.getEmitter().triggerCue(this.combinedEngineSound);
                } else {
                    this.getEmitter().stopSound(this.combinedEngineSound);
                }

                this.combinedEngineSound = 0L;
            }
        }
    }

    public BaseVehicle setSmashed(String location) {
        return this.setSmashed(location, false);
    }

    public BaseVehicle setSmashed(String location, boolean flipped) {
        String string = null;
        Integer integer = null;
        KahluaTableImpl kahluaTableImpl0 = (KahluaTableImpl)LuaManager.env.rawget("SmashedCarDefinitions");
        if (kahluaTableImpl0 != null) {
            KahluaTableImpl kahluaTableImpl1 = (KahluaTableImpl)kahluaTableImpl0.rawget("cars");
            if (kahluaTableImpl1 != null) {
                KahluaTableImpl kahluaTableImpl2 = (KahluaTableImpl)kahluaTableImpl1.rawget(this.getScriptName());
                if (kahluaTableImpl2 != null) {
                    string = kahluaTableImpl2.rawgetStr(location.toLowerCase());
                    integer = kahluaTableImpl2.rawgetInt("skin");
                    if (integer == -1) {
                        integer = this.getSkinIndex();
                    }
                }
            }
        }

        int _int = this.getKeyId();
        if (string != null) {
            this.removeFromWorld();
            this.permanentlyRemove();
            BaseVehicle baseVehicle = new BaseVehicle(IsoWorld.instance.CurrentCell);
            baseVehicle.setScriptName(string);
            baseVehicle.setScript();
            baseVehicle.setSkinIndex(integer);
            baseVehicle.setX(this.x);
            baseVehicle.setY(this.y);
            baseVehicle.setZ(this.z);
            baseVehicle.setDir(this.getDir());
            baseVehicle.savedRot.set(this.savedRot);
            if (flipped) {
                float _float = this.getAngleY();
                baseVehicle.savedRot.rotationXYZ(0.0F, _float * (float) (Math.PI / 180.0), (float) Math.PI);
            }

            baseVehicle.jniTransform.setRotation(baseVehicle.savedRot);
            if (IsoChunk.doSpawnedVehiclesInInvalidPosition(baseVehicle)) {
                baseVehicle.setSquare(this.square);
                baseVehicle.square.chunk.vehicles.add(baseVehicle);
                baseVehicle.chunk = baseVehicle.square.chunk;
                baseVehicle.addToWorld();
                VehiclesDB2.instance.addVehicle(baseVehicle);
            }

            baseVehicle.setGeneralPartCondition(0.5F, 60.0F);
            VehiclePart vehiclePart = baseVehicle.getPartById("Engine");
            if (vehiclePart != null) {
                vehiclePart.setCondition(0);
            }

            baseVehicle.engineQuality = 0;
            baseVehicle.setKeyId(_int);
            return baseVehicle;
        } else {
            return this;
        }
    }

    public boolean isCollided(IsoGameCharacter character) {
        if (GameClient.bClient && this.getDriver() != null && !this.getDriver().isLocal()) {
            return true;
        } else {
            Vector2 vector2 = this.testCollisionWithCharacter(character, 0.20000002F, this.hitVars.collision);
            return vector2 != null && vector2.x != -1.0F;
        }
    }

    public BaseVehicle.HitVars checkCollision(IsoGameCharacter target) {
        if (target.isProne()) {
            int _int = this.testCollisionWithProneCharacter(target, true);
            if (_int > 0) {
                this.hitVars.calc(target, this);
                this.hitCharacter(target, this.hitVars);
                return this.hitVars;
            } else {
                return null;
            }
        } else {
            this.hitVars.calc(target, this);
            this.hitCharacter(target, this.hitVars);
            return this.hitVars;
        }
    }

    public boolean updateHitByVehicle(IsoGameCharacter target) {
        if (target.isVehicleCollisionActive(this) && (this.isCollided(target) || target.isCollidedWithVehicle()) && this.physics != null) {
            BaseVehicle.HitVars hitVarsx = this.checkCollision(target);
            if (hitVarsx != null) {
                target.doHitByVehicle(this, hitVarsx);
                return true;
            }
        }

        return false;
    }

    public void hitCharacter(IsoGameCharacter character, BaseVehicle.HitVars vars) {
        if (vars.dot < 0.0F && !GameServer.bServer) {
            this.ApplyImpulse(character, vars.vehicleImpulse);
        }

        long long0 = System.currentTimeMillis();
        long long1 = (long0 - this.zombieHitTimestamp) / 1000L;
        this.zombiesHits = Math.max(this.zombiesHits - (int)long1, 0);
        if (long0 - this.zombieHitTimestamp > 700L) {
            this.zombieHitTimestamp = long0;
            this.zombiesHits++;
            this.zombiesHits = Math.min(this.zombiesHits, 20);
        }

        if (character instanceof IsoPlayer) {
            ((IsoPlayer)character).setVehicleHitLocation(this);
        } else if (character instanceof IsoZombie) {
            ((IsoZombie)character).setVehicleHitLocation(this);
        }

        if (vars.vehicleSpeed >= 5.0F || this.zombiesHits > 10) {
            vars.vehicleSpeed = this.getCurrentSpeedKmHour() / 5.0F;
            Vector3f vector3f = ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).alloc();
            this.getLocalPos(character.x, character.y, character.z, vector3f);
            if (vector3f.z > 0.0F) {
                int int0 = this.caclulateDamageWithBodies(true);
                if (!GameClient.bClient) {
                    this.addDamageFrontHitAChr(int0);
                }

                DebugLog.Vehicle.trace("Damage car front hits=%d damage=%d", this.zombiesHits, int0);
                vars.vehicleDamage = int0;
                vars.isVehicleHitFromFront = true;
            } else {
                int int1 = this.caclulateDamageWithBodies(false);
                if (!GameClient.bClient) {
                    this.addDamageRearHitAChr(int1);
                }

                DebugLog.Vehicle.trace("Damage car rear hits=%d damage=%d", this.zombiesHits, int1);
                vars.vehicleDamage = int1;
                vars.isVehicleHitFromFront = false;
            }

            ((BaseVehicle.Vector3fObjectPool)TL_vector3f_pool.get()).release(vector3f);
        }
    }

    public static enum Authorization {
        Server,
        LocalCollide,
        RemoteCollide,
        Local,
        Remote;

        private static final HashMap<Byte, BaseVehicle.Authorization> authorizations = new HashMap();

        public static BaseVehicle.Authorization valueOf(byte _byte) {
            return (BaseVehicle.Authorization)authorizations.getOrDefault(_byte, Server);
        }

        public byte index() {
            return (byte)this.ordinal();
        }

        static {
            Arrays.stream(values()).forEach(authorization -> authorizations.put(authorization.index(), authorization));
        }
    }

    public static class HitVars {
        private static final float speedCap = 10.0F;
        private final Vector3f velocity = new Vector3f();
        private final Vector2 collision = new Vector2();
        private float dot;
        protected float vehicleImpulse;
        protected float vehicleSpeed;
        public final Vector3f targetImpulse = new Vector3f();
        public boolean isVehicleHitFromFront;
        public boolean isTargetHitFromBehind;
        public int vehicleDamage;
        public float hitSpeed;

        public void calc(IsoGameCharacter target, BaseVehicle vehicle) {
            vehicle.getLinearVelocity(this.velocity);
            this.velocity.y = 0.0F;
            if (target instanceof IsoZombie) {
                this.vehicleSpeed = Math.min(this.velocity.length(), 10.0F);
                this.hitSpeed = this.vehicleSpeed + vehicle.getClientForce() / vehicle.getFudgedMass();
            } else {
                this.vehicleSpeed = (float)Math.sqrt((double)(this.velocity.x * this.velocity.x + this.velocity.z * this.velocity.z));
                if (target.isOnFloor()) {
                    this.hitSpeed = Math.max(this.vehicleSpeed * 6.0F, 5.0F);
                } else {
                    this.hitSpeed = Math.max(this.vehicleSpeed * 2.0F, 5.0F);
                }
            }

            this.targetImpulse.set(vehicle.x - target.x, 0.0F, vehicle.y - target.y);
            this.targetImpulse.normalize();
            this.velocity.normalize();
            this.dot = this.velocity.dot(this.targetImpulse);
            this.targetImpulse.normalize();
            this.targetImpulse.mul(3.0F * this.vehicleSpeed / 10.0F);
            this.targetImpulse.set(this.targetImpulse.x, this.targetImpulse.y, this.targetImpulse.z);
            this.vehicleImpulse = vehicle.getFudgedMass() * 7.0F * this.vehicleSpeed / 10.0F * Math.abs(this.dot);
            this.isTargetHitFromBehind = "BEHIND".equals(target.testDotSide(vehicle));
        }
    }

    private static final class L_testCollisionWithVehicle {
        static final Vector2[] testVecs1 = new Vector2[4];
        static final Vector2[] testVecs2 = new Vector2[4];
        static final Vector3f worldPos = new Vector3f();
    }

    public static final class Matrix4fObjectPool extends ObjectPool<Matrix4f> {
        int allocated = 0;

        Matrix4fObjectPool() {
            super(Matrix4f::new);
        }

        protected Matrix4f makeObject() {
            this.allocated++;
            return (Matrix4f)super.makeObject();
        }
    }

    public static final class MinMaxPosition {
        public float minX;
        public float maxX;
        public float minY;
        public float maxY;
    }

    public static final class ModelInfo {
        public VehiclePart part;
        public VehicleScript.Model scriptModel;
        public ModelScript modelScript;
        public int wheelIndex;
        public final Matrix4f renderTransform = new Matrix4f();
        public VehicleSubModelInstance modelInstance;
        public AnimationPlayer m_animPlayer;
        public AnimationTrack m_track;

        public AnimationPlayer getAnimationPlayer() {
            if (this.part != null && this.part.getParent() != null) {
                BaseVehicle.ModelInfo modelInfo1 = this.part.getVehicle().getModelInfoForPart(this.part.getParent());
                if (modelInfo1 != null) {
                    return modelInfo1.getAnimationPlayer();
                }
            }

            String string = this.scriptModel.file;
            Model model = ModelManager.instance.getLoadedModel(string);
            if (model != null && !model.bStatic) {
                if (this.m_animPlayer != null && this.m_animPlayer.getModel() != model) {
                    this.m_animPlayer = Pool.tryRelease(this.m_animPlayer);
                }

                if (this.m_animPlayer == null) {
                    this.m_animPlayer = AnimationPlayer.alloc(model);
                }

                return this.m_animPlayer;
            } else {
                return null;
            }
        }

        public void releaseAnimationPlayer() {
            this.m_animPlayer = Pool.tryRelease(this.m_animPlayer);
        }
    }

    public static final class Passenger {
        public IsoGameCharacter character;
        final Vector3f offset = new Vector3f();
    }

    public static final class QuaternionfObjectPool extends ObjectPool<Quaternionf> {
        int allocated = 0;

        QuaternionfObjectPool() {
            super(Quaternionf::new);
        }

        protected Quaternionf makeObject() {
            this.allocated++;
            return (Quaternionf)super.makeObject();
        }
    }

    public static final class ServerVehicleState {
        public float x = -1.0F;
        public float y;
        public float z;
        public Quaternionf orient = new Quaternionf();
        public short flags;
        public BaseVehicle.Authorization netPlayerAuthorization = BaseVehicle.Authorization.Server;
        public short netPlayerId = 0;

        public ServerVehicleState() {
            this.flags = 0;
        }

        public void setAuthorization(BaseVehicle vehicle) {
            this.netPlayerAuthorization = vehicle.netPlayerAuthorization;
            this.netPlayerId = vehicle.netPlayerId;
        }

        public boolean shouldSend(BaseVehicle vehicle) {
            if (vehicle.getController() == null) {
                return false;
            } else if (vehicle.updateLockTimeout > System.currentTimeMillis()) {
                return false;
            } else {
                this.flags = (short)(this.flags & 1);
                if (!vehicle.isNetPlayerAuthorization(this.netPlayerAuthorization) || !vehicle.isNetPlayerId(this.netPlayerId)) {
                    this.flags = (short)(this.flags | 16384);
                }

                this.flags = (short)(this.flags | vehicle.updateFlags);
                return this.flags != 0;
            }
        }
    }

    protected static class UpdateFlags {
        public static final short Full = 1;
        public static final short PositionOrientation = 2;
        public static final short Engine = 4;
        public static final short Lights = 8;
        public static final short PartModData = 16;
        public static final short PartUsedDelta = 32;
        public static final short PartModels = 64;
        public static final short PartItem = 128;
        public static final short PartWindow = 256;
        public static final short PartDoor = 512;
        public static final short Sounds = 1024;
        public static final short PartCondition = 2048;
        public static final short UpdateCarProperties = 4096;
        public static final short Authorization = 16384;
        public static final short AllPartFlags = 19440;
    }

    public static final class Vector2ObjectPool extends ObjectPool<Vector2> {
        int allocated = 0;

        Vector2ObjectPool() {
            super(Vector2::new);
        }

        protected Vector2 makeObject() {
            this.allocated++;
            return (Vector2)super.makeObject();
        }
    }

    public static final class Vector2fObjectPool extends ObjectPool<Vector2f> {
        int allocated = 0;

        Vector2fObjectPool() {
            super(Vector2f::new);
        }

        protected Vector2f makeObject() {
            this.allocated++;
            return (Vector2f)super.makeObject();
        }
    }

    public static final class Vector3fObjectPool extends ObjectPool<Vector3f> {
        int allocated = 0;

        Vector3fObjectPool() {
            super(Vector3f::new);
        }

        protected Vector3f makeObject() {
            this.allocated++;
            return (Vector3f)super.makeObject();
        }
    }

    private static final class VehicleImpulse {
        static final ArrayDeque<BaseVehicle.VehicleImpulse> pool = new ArrayDeque();
        final Vector3f impulse = new Vector3f();
        final Vector3f rel_pos = new Vector3f();
        boolean enable = false;

        static BaseVehicle.VehicleImpulse alloc() {
            return pool.isEmpty() ? new BaseVehicle.VehicleImpulse() : (BaseVehicle.VehicleImpulse)pool.pop();
        }

        void release() {
            pool.push(this);
        }
    }

    public static final class WheelInfo {
        public float steering;
        public float rotation;
        public float skidInfo;
        public float suspensionLength;
    }

    public static enum engineStateTypes {
        Idle,
        Starting,
        RetryingStarting,
        StartingSuccess,
        StartingFailed,
        Running,
        Stalling,
        ShutingDown,
        StartingFailedNoPower;

        public static final BaseVehicle.engineStateTypes[] Values = values();
    }
}
